有两个数组:
[
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
{"id": "344430b94t4t34rwefewfdff", "quantity": 5},
{"id": "342343343t4t34rwefewfd53", "quantity": 3}
]
和
[
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
{"id": "344430b94t4t34rwefewfdff", "quantity": 1}
]
如何将它们合并为一个求和数量?
[
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 3},
{"id": "344430b94t4t34rwefewfdff", "quantity": 6},
{"id": "342343343t4t34rwefewfd53", "quantity": 3}
]
其中之一有时可能是空的
答案 0 :(得分:3)
您可以使用普通的JavaScript来实现。
使用Array.reduce()
通过id制作一个中间字典并累加数量,然后用Object.values()
将其变成一个数组:
const arr1 = [
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
{"id": "344430b94t4t34rwefewfdff", "quantity": 5},
{"id": "342343343t4t34rwefewfd53", "quantity": 3}
];
const arr2 = [
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
{"id": "344430b94t4t34rwefewfdff", "quantity": 1}
];
const result = Object.values([...arr1, ...arr2].reduce((acc, { id, quantity }) => {
acc[id] = { id, quantity: (acc[id] ? acc[id].quantity : 0) + quantity };
return acc;
}, {}));
console.log(result);
答案 1 :(得分:2)
您可以使用lodash,但是现代香草JS既可行又高效。我想其他答案将使用类似reduce
之类的功能性方法,所以这是一个使用带有find
的简单for/of
循环而不是可能更长的字典查找的版本,但是比较容易理解。
const arr1 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1}, {"id": "344430b94t4t34rwefewfdff", "quantity": 5}, {"id": "342343343t4t34rwefewfd53", "quantity": 3}];
const arr2 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2}, {"id": "344430b94t4t34rwefewfdff", "quantity": 1}];
function merge(arr1, arr2) {
// Merge the arrays, and set up an output array.
const merged = [...arr1, ...arr2];
const out = [];
// Loop over the merged array
for (let obj of merged) {
// Destructure the object in the current iteration to get
// its id and quantity values
const { id, quantity } = obj;
// Find the object in out that has the same id
const found = out.find(obj => obj.id === id);
// If an object *is* found add this object's quantity to it...
if (found) {
found.quantity += quantity;
// ...otherwise push a copy of the object to out
} else {
out.push({ ...obj });
}
}
return out;
}
console.log(merge(arr1, arr2));
答案 2 :(得分:1)
您可以通过reduce来做到这一点:
let a1 = [
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2},
{"id": "344430b94t4t34rwefewfdff", "quantity": 1}
];
let a2 = [
{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1},
{"id": "344430b94t4t34rwefewfdff", "quantity": 5},
{"id": "342343343t4t34rwefewfd53", "quantity": 3}
];
let result = Object.values(a1.concat(a2).reduce((acc, v) => {
if (!acc[v.id]) {
acc[v.id] = {id: v.id, quantity: 0};
}
acc[v.id].quantity += v.quantity;
return acc;
}, {}));
console.log("Results: ", result);
答案 3 :(得分:0)
带有附加对象键的版本。 函数的主体不会干扰具有属性的对象。 因此,以“数量”求和,然后以“ prop”检查
var first = [
{quantity:100, id:1, variantId: 1},
{quantity:300, id:2, variantId: 2, propA: 'aaa'},
];
var second = [
{quantity:100, id:1, variantId: 1},
{quantity:200, id:2, variantId: 2, propB: true},
{quantity:300, id:3, variantId: 3, propC: 'ccc'},
]
function mergeArrays(arrayOfArrays, propToCheck, propToSum) {
let sum = [];
[].concat(...arrayOfArrays).map(function(o) {
let existing = sum.filter(function(i) { return i[propToCheck] === o[propToCheck] })[0];
if (!existing) {
sum.push(o);
} else {
existing[propToSum] += o[propToSum];
let copyProps = Object.keys(o).filter(obj => {
return existing[obj] !== o[obj]
}).map(val => (val !== propToSum) ? existing[val] = o[val] : null)
}
});
return sum;
}
console.log(mergeArrays([first, second], 'variantId', 'quantity'))
答案 4 :(得分:0)
您可以使用.reduce和.find方法来实现。
const arr1 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 1}, {"id": "344430b94t4t34rwefewfdff", "quantity": 5}, {"id": "342343343t4t34rwefewfd53", "quantity": 3}];
const arr2 = [{"id": "5c5030b9a1ccb11fe8c321f4", "quantity": 2}, {"id": "344430b94t4t34rwefewfdff", "quantity": 1}];
const result = [...arr1, ...arr2].reduce((accumulator, currentValue) => {
const element = accumulator.find(item => item.id === currentValue.id)
element ? element.quantity += currentValue.quantity : accumulator.push(currentValue)
return accumulator
},[])
console.log(result)
答案 5 :(得分:0)
所有这些答案都要求您知道要选择和求和的对象结构。
lodash 实际上允许您在不知道结构的情况下执行此操作;通过使用 customizer
的 _.mergeWidth
参数;
let result = _.mergeWith(arr1, arr2, (objValue, srcValue, key, object, source, stack) =>{
//Add any conditions you need here. Ive added a few relevant examples.
//if(key.startsWith("num")) //Check for property name prefixes like num...
//if(propertyNamesToSum.Includes(key)) //check if your property is in your predefined list of property names
//This one below sums any properties that are numbers
if(_.isNumber(srcValue) && _.isNumber(objValue)){
return srcValue + objValue;
}
return undefined; //lodash will merge as usual if you return undefined.
});
Lodash 文档 - https://lodash.com/docs/4.17.15#mergeWith