假设我有两个列表
const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
const listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]
问题是如何将两个列表合并为一个以数字增量堆叠相同的项目并按数量排序?我的意思是最终结果应该是->
const listMerged = [{"apple":115}, {"banana": 50} , {"peach": 30}, {"kiwi": 13}, {"pearl": 10}, {"cherry": 5}, {"mango": 5}]
我知道它会像:
sortListDesc(list) {
return obj.sort(function (l1,l2) {
return l2< l1 ? -1
: l2 >l1 ? 1
: 0
})
}
但不确切知道如何堆叠数字,而不是按数量排序。
reduce
,sort
和Object.values
如下所示:
const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
, listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]
let merged = Object.values(listA.concat(listB).reduce((acc, a) => {
const [k, v] = Object.entries(a)[0];
(acc[k] = acc[k] || {[k]: 0})[k] += v;
return acc;
}, {}));
merged.sort((a, b) => Object.values(b)[0] - Object.values(a)[0]);
console.log(merged);
或
使用 reduce
创建一个对象,将所有水果作为键,单个总和作为值。然后像这样使用 Object.entries
、sort
和 map
:
const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
, listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]
let merged2 = listA.concat(listB).reduce((acc, a) => {
const [k, v] = Object.entries(a)[0];
acc[k] = (acc[k] || 0) + v;
return acc;
}, {});
const final = Object.entries(merged2)
.sort(([, v1], [, v2]) => v2 - v1)
.map(([k, v]) => ({[k]: v}))
console.log(final);
forEach
迭代第二个列表,并使用findIndex
检查第一个列表中是否存在相同的元素。如果元素不存在(-1),则将元素推入第一个列表。如果存在,则使用索引获取该对象,然后在for..in
内更新其值
const listA = [{
"apple": 100
}, {
"banana": 50
}, {
"pearl": 10
}, {
"cherry": 5
}, {
"kiwi": 3
}]
const listB = [{
"peach": 30
}, {
"apple": 15
}, {
"kiwi": 10
}, {
"mango": 5
}]
let newArr = listB.forEach((item) => {
let ifElemPresentInListA = listA.findIndex((elem) => {
return Object.keys(elem)[0] === Object.keys(item)[0]
})
if (ifElemPresentInListA === -1) {
listA.push(item)
} else {
for (let keys in listA[ifElemPresentInListA]) {
listA[ifElemPresentInListA][keys] += Object.values(item)[0]
}
}
})
console.log(listA)
我的代码比 brk 的代码稍微干净一些
const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
const listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]
const both = Object.assign({}, ... listA, ... listB); // concatenate both lists and convert them to an object
const lA = Object.assign({}, ...listA); // convert listA to an object
const lB = Object.assign({}, ...listB);
var result = Object.keys(both).map( (a) => { // mapping sums the values and yields an array
var sum = {};
sum [a] =(lA[a] ? lA[a] : 0) + (lB[a] ? lB[a] : 0);
return sum;
});
// sorting in desc order (hence b - a ) based on values (hence b[Object.keys(b)]) rather than keys
result.sort((a,b) => b[Object.keys(b)] - a[Object.keys(a)] );
复杂性是由于您将值存储为数组。我相信这不是最好的方法,因为数组可以有多个具有相同键的元素。例如,你最终可能会得到这样的东西: const listA = [{"apple":100},...,{"apple":10}]
有效但可能会产生问题。我建议您考虑将其用作对象,例如: const listA = {{'apple': 100}, {'banana':50}}
这将大大简化代码,并确保您没有重复项
希望对您有所帮助!