Я трохи запізнююсь до партії, однак, якщо вам потрібне більш надійне та гнучке рішення, то ось мій внесок. Якщо ви хочете підсумувати лише конкретну властивість у вкладеному комбінованому об’єкті / масиві, а також виконати інші агреговані методи, то ось невелика функція, яку я використовував у проекті 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 = або
властивість об'єкта, або масиву = властивість усередині вкладених об'єктів / масивів, для яких ви хочете виконати метод
агрегату на agregate = метод агрегації (сума, мінімум, максимум або кількість)
shallow = може бути встановлено значення true / false або числове значення
глибина = слід залишити нулем або невизначеним (воно використовується для відстеження наступних рекурсивних зворотних викликів)
Неглибоку можна використовувати для підвищення продуктивності, якщо ви знаєте, що вам не потрібно буде шукати глибоко вкладені дані. Наприклад, якщо у вас був такий масив:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
Якщо ви хочете уникнути перегляду властивості otherData, оскільки значення, яке ви збираєтеся агрегувати, не вкладене настільки глибоко, ви можете встановити для shallow значення true.