Группировка элементов в массиве по нескольким свойствам является самым близким совпадением с моим вопросом, поскольку она действительно группирует объекты по нескольким ключам в массиве. Проблема заключается в том, что это решение не суммирует значение свойств, а затем удаляет дубликаты, вместо этого он вставляет все дубликаты в двумерные массивы.
Ожидаемое поведение
У меня есть массив объектов, которые должны быть сгруппированы по 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}
];
Объекты в этом массиве считаются дублирующимися, только если их shape
и color
одинаковы. Если они есть, я хочу, соответственно, суммировать их used
и значения instances
а затем удалить дубликаты.
Таким образом, в этом примере массив результатов может содержать только четыре комбинации: square red
, square blue
, circle red
, circle 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);