Я немного опоздал с вечеринкой, однако, если вам требуется более надежное и гибкое решение, вот мой вклад. Если вы хотите суммировать только определенное свойство во вложенной комбинации объект / массив, а также выполнять другие агрегированные методы, то вот небольшая функция, которую я использовал в проекте React:
var aggregateProperty = function(obj, property, aggregate, shallow, depth) {
if ((typeof obj !== 'object' && typeof obj !== 'array') || !property) {
return;
}
obj = JSON.parse(JSON.stringify(obj));
const validAggregates = [ 'sum', 'min', 'max', 'count' ];
aggregate = (validAggregates.indexOf(aggregate.toLowerCase()) !== -1 ? aggregate.toLowerCase() : 'sum');
if (shallow === true) {
shallow = 2;
} else if (isNaN(shallow) || shallow < 2) {
shallow = false;
}
if (isNaN(depth)) {
depth = 1;
}
var value = ((aggregate == 'min' || aggregate == 'max') ? null : 0);
for (var prop in obj) {
if (!obj.hasOwnProperty(prop)) {
continue;
}
var propValue = obj[prop];
var nested = (typeof propValue === 'object' || typeof propValue === 'array');
if (nested) {
if (prop == property && aggregate == 'count') {
value++;
}
if (shallow === false || depth < shallow) {
propValue = aggregateProperty(propValue, property, aggregate, shallow, depth+1);
} else {
continue;
}
}
if ((prop == property || nested) && propValue) {
switch(aggregate) {
case 'sum':
if (!isNaN(propValue)) {
value += propValue;
}
break;
case 'min':
if ((propValue < value) || !value) {
value = propValue;
}
break;
case 'max':
if ((propValue > value) || !value) {
value = propValue;
}
break;
case 'count':
if (propValue) {
if (nested) {
value += propValue;
} else {
value++;
}
}
break;
}
}
}
return value;
}
Он рекурсивный, не ES6, и он должен работать в большинстве полусовременных браузеров. Вы используете это так:
const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');
Разбивка параметров:
obj = либо объект, либо
свойство массива = свойство внутри вложенных объектов / массивов, которое вы хотите выполнить агрегатным методом для
агрегата = агрегатный метод (сумма, мин., макс. или счетчик)
shallow = может иметь значение true / false или числовое значение
depth = следует оставить null или undefined (используется для отслеживания последующих рекурсивных обратных вызовов)
Shallow можно использовать для повышения производительности, если вы знаете, что вам не нужно искать глубоко вложенные данные. Например, если у вас был следующий массив:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
Если вы хотите избежать цикла по свойству otherData, поскольку значение, которое вы собираетесь агрегировать, не вложено так глубоко, вы можете установить shallow на true.