通过数组中的多个属性对对象进行分组,然后对其值求和

通过多个属性对数组中的元素进行分组最符合我的问题,因为它确实通过数组中的多个键对对象进行了分组。问题是此解决方案无法汇总属性值,然后删除重复项,而是将所有重复项嵌套在二维数组中。

我有一个对象数组,必须按shape和进行分组color

var arr = [

{shape: 'square', color: 'red', used: 1, instances: 1},

{shape: 'square', color: 'red', used: 2, instances: 1},

{shape: 'circle', color: 'blue', used: 0, instances: 0},

{shape: 'square', color: 'blue', used: 4, instances: 4},

{shape: 'circle', color: 'red', used: 1, instances: 1},

{shape: 'circle', color: 'red', used: 1, instances: 0},

{shape: 'square', color: 'blue', used: 4, instances: 5},

{shape: 'square', color: 'red', used: 2, instances: 1}

];

这个数组中的对象被视为重复仅当其shapecolor是相同的。如果它们是,我想分别总结它们的usedinstances值,然后删除重复项。

因此,在这个例子的结果阵列可以仅含有四种组合:square redsquare bluecircle redcircle blue

我在这里尝试了一种更简单的方法:

var arr = [

{shape: 'square', color: 'red', used: 1, instances: 1},

{shape: 'square', color: 'red', used: 2, instances: 1},

{shape: 'circle', color: 'blue', used: 0, instances: 0},

{shape: 'square', color: 'blue', used: 4, instances: 4},

{shape: 'circle', color: 'red', used: 1, instances: 1},

{shape: 'circle', color: 'red', used: 1, instances: 0},

{shape: 'square', color: 'red', used: 4, instances: 4},

{shape: 'square', color: 'red', used: 2, instances: 2}

];

result = [];

arr.forEach(function (a) {

if ( !this[a.color] && !this[a.shape] ) {

this[a.color] = { color: a.color, shape: a.shape, used: 0, instances: 0 };

result.push(this[a.color]);

}

this[a.color].used += a.used;

this[a.color].instances += a.instances;

}, Object.create(null));

console.log(result);

但它输出

[{shape: "square", color: "red", used: 11, instances: 9},

{shape: "circle", color: "blue", used: 4, instances: 4}]

而不是预期的结果:

[{shape: "square", color: "red", used: 5, instances: 3},

{shape: "circle", color: "red", used: 2, instances: 1},

{shape: "square", color: "blue", used: 11, instances: 9},

{shape: "circle", color: "blue", used: 0, instances: 0}]

如何获得按形状和颜色正确分组对象的功能?即总结他们的价值,并删除重复的?

回答:

将Array#reduce与帮助器对象一起使用可以对相似的对象进行分组。对于每个对象,检查合并的shape和是否color存在于帮助器中。如果不是,请使用Object#assign添加到帮助器中以创建对象的副本,然后将其压入数组。如果是这样,请将其值添加到usedinstances

var arr = [{"shape":"square","color":"red","used":1,"instances":1},{"shape":"square","color":"red","used":2,"instances":1},{"shape":"circle","color":"blue","used":0,"instances":0},{"shape":"square","color":"blue","used":4,"instances":4},{"shape":"circle","color":"red","used":1,"instances":1},{"shape":"circle","color":"red","used":1,"instances":0},{"shape":"square","color":"blue","used":4,"instances":5},{"shape":"square","color":"red","used":2,"instances":1}];

var helper = {};

var result = arr.reduce(function(r, o) {

var key = o.shape + '-' + o.color;

if(!helper[key]) {

helper[key] = Object.assign({}, o); // create a copy of o

r.push(helper[key]);

} else {

helper[key].used += o.used;

helper[key].instances += o.instances;

}

return r;

}, []);

console.log(result);

如果你可以使用ES6,您可以使用地图收集的值,然后将其转换回一个数组蔓延的地图#值:

const arr = [{"shape":"square","color":"red","used":1,"instances":1},{"shape":"square","color":"red","used":2,"instances":1},{"shape":"circle","color":"blue","used":0,"instances":0},{"shape":"square","color":"blue","used":4,"instances":4},{"shape":"circle","color":"red","used":1,"instances":1},{"shape":"circle","color":"red","used":1,"instances":0},{"shape":"square","color":"blue","used":4,"instances":5},{"shape":"square","color":"red","used":2,"instances":1}];

const result = [...arr.reduce((r, o) => {

const key = o.shape + '-' + o.color;

const item = r.get(key) || Object.assign({}, o, {

used: 0,

instances: 0

});

item.used += o.used;

item.instances += o.instances;

return r.set(key, item);

}, new Map).values()];

console.log(result);

以上是 通过数组中的多个属性对对象进行分组,然后对其值求和 的全部内容, 来源链接: utcz.com/qa/430487.html

回到顶部