我有多个数组,看起来像这样
第一个对象数组看起来像这样
Array[4]
0 : Object
price:"2"
ref:"A"
1 : Object
price:"20"
ref:"B"
2 : Object
price:"23"
ref:"C"
3 : Object
price:"23"
ref:"D"
第二个对象数组看起来像这样
Array[4]
0 : Object
price:"12"
ref:"A"
1 : Object
price:"5"
ref:"B"
2 : Object
price:"23"
ref:"E"
3 : Object
price:"23"
ref:"F"
我的第三个对象看起来像这样。
Array[2]
0 : Object
name:"Blah"
fcp:"erol"
1 : Object
name:"Blah2"
fcp:"tpep"
现在我想根据price
对ref
求和。第一个对象和第二个对象具有参考A和B的共同点。这样最终的对象看起来像
Array[7]
0 : Object
price:"14"
ref:"A"
1 : Object
price:"25"
ref:"B"
2 : Object
price:"23"
ref:"C"
3 : Object
price:"23"
ref:"D"
4 : Object
price:"23"
ref:"E"
5 : Object
price:"23"
ref:"F"
6 : Object
name:"Blah"
fcp:"erol"
7 : Object
name:"Blah2"
fcp:"tpep"
答案 0 :(得分:5)
您可以使用reduce功能进行抓取
var array1 = [{
price: "2",
ref: "A"
},
{
price: "20",
ref: "B"
},
{
price: "23",
ref: "C"
},
{
price: "23",
ref: "D"
}
];
var array2 = [{
price: "12",
ref: "A"
},
{
price: "5",
ref: "B"
},
{
price: "23",
ref: "E"
},
{
price: "23",
ref: "F"
}
];
var array3 = [{
name: "Blah",
fcp: "erol"
},
{
name: "Blah2",
fcp: "tpep"
}
];
var result = array1.concat(array2, array3).reduce(function(acc, curr) {
if (curr.ref) {
var fromMap = acc.map[curr.ref];
if (!fromMap) {
acc.map[curr.ref] = fromMap = {
price: 0,
ref: curr.ref
}
acc.result.push(fromMap);
}
fromMap.price += parseFloat(curr.price);
} else {
acc.result.push(curr);
}
return acc;
}, {
map: {},
result: []
}).result;
console.log(result);
答案 1 :(得分:0)
<强>更新强>
我稍微调整了以前解决方案中的代码,使其以线性时间O(n)
运行,通过维护“hashmap”使其稍微快一点。对于原始问题中给定大小的数组,性能增强将为零,但它仍然是更快的解决方案。
// concat all items of all arrays into a big array
var bigArray = [].concat(array1, array2, array3);
// maintain a hashmap to track if "ref" exists at any index in any previous obj of array
// key=ref, value=index-where-ref-exists
var hash = {};
// loop over bigArray
for (var i = 0; i < bigArray.length; i++) {
// current obj we are processing
var currObj = bigArray[i];
// change price to number format
var priceInNumberFormat = parseFloat(currObj.price);
// if price is not a valid number, move onto processing next obj
if (!isNumber(priceInNumberFormat)) {
continue;
}
// update currentObj's "price" property. We need it to be in number format so we could do addition
currObj.price = priceInNumberFormat;
// check if any obj exits with same ref value.
if (hash[currObj.ref] !== undefined) {
var idx = hash[currObj.ref]; // index of existing obj with same "ref"
bigArray[idx].price += currObj.price;
bigArray.splice(i, 1);
// backtrack on "i" value since we shortened the length of the array
i--;
} else {
hash[currObj.ref] = i;
}
}
以前的解决方案:
以下是一种可能的解决方案:
var array1 = [
{ price:"2", ref:"A" },
{ price:"20", ref:"B" },
{ price:"23", ref:"C" },
{ price:"23", ref:"D" }
];
var array2 = [
{ price:"12", ref:"A" },
{ price:"5", ref:"B" },
{ price:"23", ref:"E" },
{ price:"23", ref:"F" }
];
var array3 = [
{ name:"Blah", fcp:"erol" },
{ name:"Blah2", fcp:"tpep" }
];
// helper function to determine if a arg is valid number
function isNumber (num) {
return (typeof num === 'number' && !isNaN(num));
}
// concat all items of all arrays into a big array
var bigArray = [].concat(array1, array2, array3);
// loop over bigArray
for (var i = 0; i < bigArray.length; i++) {
// current obj we are processing
var currObj = bigArray[i];
// change price to number format
var iPriceInNumberFormat = parseFloat(currObj.price);
// if price is not a valid number, move onto processing next obj
if (!isNumber(iPriceInNumberFormat)) {
continue;
}
// update currentObj's "price" property. We need it to be in number format so we could do addition
currObj.price = iPriceInNumberFormat;
// now loop over remaining items of bigArray
for (var j = i+1; j < bigArray.length; j++) {
// if there is another object further down bigArray with same "ref" value as currObj
if (currObj.ref === bigArray[j].ref) {
// convert its price to number format as well
var jPriceInNumberFormat = parseFloat(bigArray[j].price);
// if its not a valid number, move onto next obj
if (!isNumber(jPriceInNumberFormat)) {
continue;
}
// otherwise add its price value to currObj's price
currObj.price += jPriceInNumberFormat;
// since we have added the price of this obj, discard it.
// remove bigArray[j] from bigArray
bigArray.splice(j, 1);
}
}
}
// now bigArray has removed all objects with duplicate "ref" values, and has their prices added
console.log(bigArray);
// should print bigArray value as expected solution:
// [ { price: 14, ref: 'A' },
// { price: 25, ref: 'B' },
// { price: 23, ref: 'C' },
// { price: 23, ref: 'D' },
// { price: 23, ref: 'E' },
// { price: 23, ref: 'F' },
// { name: 'Blah', fcp: 'erol' },
// { name: 'Blah2', fcp: 'tpep' } ]