Я немного запоздал к партии, однако, если вам требуется более надежное и гибкое решение, то вот мой вклад. Если вы хотите, чтобы подвести только определенное свойство во вложенном комбе объекта/массиве, а также выполнять другие агрегатные методы, то вот небольшая функцию я использую на React проект:
var aggregateProperty = function(obj, property, aggregate, shallow, depth) {
//return aggregated value of a specific property within an object (or array of objects..)
if ((typeof obj !== 'object' && typeof obj !== 'array') || !property) {
return;
}
obj = JSON.parse(JSON.stringify(obj)); //an ugly way of copying the data object instead of pointing to its reference (so the original data remains unaffected)
const validAggregates = [ 'sum', 'min', 'max', 'count' ];
aggregate = (validAggregates.indexOf(aggregate.toLowerCase()) !== -1 ? aggregate.toLowerCase() : 'sum'); //default to sum
//default to false (if true, only searches (n) levels deep ignoring deeply nested data)
if (shallow === true) {
shallow = 2;
} else if (isNaN(shallow) || shallow < 2) {
shallow = false;
}
if (isNaN(depth)) {
depth = 1; //how far down the rabbit hole have we travelled?
}
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) {
//the property is an object or an array
if (prop == property && aggregate == 'count') {
value++;
}
if (shallow === false || depth < shallow) {
propValue = aggregateProperty(propValue, property, aggregate, shallow, depth+1); //recursively aggregate nested objects and arrays
} else {
continue; //skip this property
}
}
//aggregate the properties value based on the selected aggregation method
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 = либо объект, либо массив
свойство = свойство в пределах вложенных объектов/массивов вы хотите выполнить агрегат Способ по
агрегатного = совокупный метод (сумма, минимум, максимум, или считать)
мелкой = может либо быть установлен в True/False или числовое значение глубины
= должно быть оставлено пустым или неопределенным (используется для отслеживания последующих рекурсивных обратных вызовов)
Shallow могут быть использованы для повышения производительности, если вы знаете, что вы не потребуется искать глубоко вложенные данные. Например, если вы имели следующий массив:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
Если вы хотите, чтобы избежать зацикливания через другие данные собственности, поскольку значение, которое вы собираетесь быть агрегирование не вложено, что глубоко, вы можете установить неглубоко истину.
Пожалуйста, подумайте об изменении принятого ответа на [мой ответ] (https://stackoverflow.com/a/39046365/3853934). –