JavaScript:使用类似属性对对象进行分组

JavaScript:使用类似属性对对象进行分组,javascript,Javascript,我有一个JavaScript对象数组,看起来像这样 [ { name: "A", value: 50 }, { name: "B", value: 20 }, { name: "C", value: 30 }, { name: "A", value: 40 }, { name: "A", value: 50 }, { name: "B", value: 70 }, { name: "A", value: 10 }, { name: "C", value:

我有一个JavaScript对象数组,看起来像这样

[ { name: "A", value: 50 },
  { name: "B", value: 20 }, 
  { name: "C", value: 30 }, 
  { name: "A", value: 40 }, 
  { name: "A", value: 50 }, 
  { name: "B", value: 70 }, 
  { name: "A", value: 10 }, 
  { name: "C", value: 50 } ]
我想在这个数组中循环并删除任何同名的重复对象,同时将它们的值添加到一起。基本而言:

[ { name: "A", value: 200 },
  { name: "B", value: 90  }, 
  { name: "C", value: 80  } ]
我知道该怎么做,伪代码:

for each object Obj in array A
    current = Obj
    for(i = (Obj's index + 1); i < A.length; i++)
        if(A[i].name = Obj.name) 
            Obj.value += A[i].value
            delete A[i]
        endif
    endfor
endfor
阵列中每个对象Obj的

电流=Obj
对于(i=(Obj的索引+1);i

我觉得这是非常低效的。有更好的方法吗?

您可以创建一个临时的“关联数组”,并遍历对象数组,如

var temp = [];
for(var i = 0; i < A.length; i++) {
    temp[A[i].name] += A[i].value;
}
A = temp;
var-temp=[];
对于(变量i=0;i

如果您试图将
A
保留为实际数组,请查看@TAGraves answer中的额外位,将其转换为实际数组。

我将使用临时对象作为中间状态,然后基于该对象创建新数组:

var arr=[{name:“A”,值:50},
{名称:“B”,值:20},
{名称:“C”,值:30},
{名称:“A”,值:40},
{名称:“A”,值:50},
{名称:“B”,值:70},
{名称:“A”,值:10},
{名称:“C”,值:50}];
var tempObj=arr.reduce(函数(newObj,obj){
if(newObj[obj.name]){
newObj[obj.name]+=obj.value;
}否则{
newObj[obj.name]=obj.value;
}
返回newObj;
}, {});
console.log(tempObj);
var结果=[];
用于(在tempObj中的变量i){
结果:推({
姓名:我,,
值:tempObj[i]
});
}

控制台日志(结果)
您可以使用
forEach()
循环和
thisArg
参数执行此操作

var data=[{name:“A”,值:50},
{名称:“B”,值:20},
{名称:“C”,值:30},
{名称:“A”,值:40},
{名称:“A”,值:50},
{名称:“B”,值:70},
{名称:“A”,值:10},
{名称:“C”,值:50}];
var结果=[];
data.forEach(函数(e){
如果(!此[e.name]){
这个[e.name]=e;
结果。推送(此[e.name]);
}否则{
此[e.name].value+=e.value;
}
}, {});

console.log(result)
您正在寻找的
reduce
和基于对象的索引:

var arr=[{name:“A”,值:50},
{名称:“B”,值:20},
{名称:“C”,值:30},
{名称:“A”,值:40},
{名称:“A”,值:50},
{名称:“B”,值:70},
{名称:“A”,值:10},
{名称:“C”,值:50}]
累计var=arr.REDUCT(功能(累加器、元件){
var currentValue=累加器[元素名称];
如果(currentValue!==未定义){
累加器[element.name]=currentValue+element.value;
}否则{
累加器[element.name]=element.value;
}
回流蓄能器;
}, {})
var result=Object.keys(累计).map(函数(k){返回{名称:k,值:累计[k]})

console.log(结果)
这是什么语言?这不是JS

在JS中,我会这样写:

array = array.filter(function(item){
    //check wether there's already an cached item for this name
    if(item.name in this){
        //then add the value to the cached item
        this[item.name].value += item.value;
        //and remove the current item from the result
        return false;
    }else{
        //otherwise cache this item
        this[item.name] = item;
        //and keep it in the result
        return true;
    }
}, {/* abusing `this` as a cache */});
您可以使用

请注意,为简单起见,将总和收集为关联数组(按
名称
分组),然后检索值以匹配预期结果

var arr=[{name:“A”,值:50},
{名称:“B”,值:20},
{名称:“C”,值:30},
{名称:“A”,值:40},
{名称:“A”,值:50},
{名称:“B”,值:70},
{名称:“A”,值:10},
{名称:“C”,值:50}];
var总和=arr.reduce(函数(acc,curr){
if(会计科目[当前名称]){
acc[curr.name].value+=curr.value;
}否则{
会计科目[当前名称]=当前;
}
返回acc;
}, {});
var res=Object.keys(sums).map(函数(键){
返回和[键];
});

控制台日志(res)this[e.name].value1+=e.value1;此[e.name].value2+=e.value2?嗨@Tomasz Pluskiewicz,我想你的代码犯了一个错误。这不是计算总和,它只是获得第一个值。是的,我改变了我的初始代码,而不是
+=
,而是
+
。谢谢你发现这个