Javascript 合并多个对象数组并对重复值求和
我有多个数组,看起来像这样Javascript 合并多个对象数组并对重复值求和,javascript,arrays,Javascript,Arrays,我有多个数组,看起来像这样 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" Ar
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[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[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"
现在我想根据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"
更新:
我在前面的解决方案中稍微调整了代码,使其在线性时间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 bigArray=[].concat(array1、array2、array3);
//维护一个hashmap来跟踪“ref”是否存在于数组的任何前一个obj的任何索引中
//key=ref,value=ref存在的索引
var hash={};
//大数组上的循环
对于(var i=0;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' } ]
var数组1=[
{价格:“2”,参考:“A”},
{价格:“20”,参考:“B”},
{价格:“23”,参考:“C”},
{价格:“23”,参考:“D”}
];
变量array2=[
{价格:“12”,参考:“A”},
{价格:“5”,参考:“B”},
{价格:“23”,参考:“E”},
{价格:“23”,参考:“F”}
];
变量数组3=[
{name:“Blah”,fcp:“erol”},
{名称:“Blah2”,fcp:“tpep”}
];
//用于确定参数是否为有效数字的helper函数
函数isNumber(num){
返回(typeof num=='number'&&&!isNaN(num));
}
//将所有数组的所有项合并为一个大数组
var bigArray=[].concat(array1、array2、array3);
//大数组上的循环
对于(var i=0;i
您可以使用此函数进行分组
var数组1=[{
价格:“2”,
参考:“A”
},
{
价格:“20”,
参考:“B”
},
{
价格:“23”,
参考:“C”
},
{
价格:“23”,
参考:“D”
}
];
变量array2=[{
价格:“12”,
参考:“A”
},
{
价格:“5”,
参考:“B”
},
{
价格:“23”,
参考:“E”
},
{
价格:“23”,
参考:“F”
}
];
变量数组3=[{
名称:“废话”,
fcp:“厄洛尔”
},
{
名称:“Blah2”,
fcp:“tpep”
}
];
var结果=array1.concat(array2,array3).reduce(函数(acc,curr){
如果(当前参考){
var fromMap=附件映射[当前参考];
如果(!fromMap){
acc.map[curr.ref]=fromMap={
价格:0,,
参考号:curr.ref
}
根据结果推送(从地图);
}
fromMap.price+=parseFloat(当前价格);
}否则{
根据结果推送(当前);
}
返回acc;
}, {
映射:{},
结果:[]
}).结果;
控制台日志(结果)代码>请您共享阵列。我猜你是从控制台拿的。对象数组包含price和ref。。最后一个对象包含名称和fcp。。也就是说,如果我想创建一个工作副本,我必须获取所有数组并手动删除0,1…&每个数组中的对象字,这不仅繁琐而且耗时。我期待一个原始格式的数组,这样我可以快速创建一个工作副本。非常感谢。