Jestem trochę spóźniony na imprezę, jednak jeśli potrzebujesz solidniejszego i bardziej elastycznego rozwiązania, oto mój wkład. Jeśli chcesz zsumować tylko określoną właściwość w zagnieżdżonej kombinacji obiekt / tablica, a także wykonać inne metody agregacji, oto mała funkcja, której używałem w projekcie 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;
}
Jest rekurencyjny, inny niż ES6 i powinien działać w większości pół-nowoczesnych przeglądarek. Używasz tego w ten sposób:
const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');
Podział parametrów:
obj = obiekt lub
właściwość tablicy = właściwość w zagnieżdżonych obiektach / tablicach, na których chcesz wykonać metodę
agregacji na agregate = metoda agregacji (suma, min, maksimum lub liczba)
płytka = może być ustawiona na true / false lub wartość liczbową
depth = należy pozostawić pustą lub niezdefiniowaną (służy do śledzenia kolejnych rekurencyjnych wywołań zwrotnych)
Shallow może służyć do zwiększenia wydajności, jeśli wiesz, że nie będziesz musiał przeszukiwać głęboko zagnieżdżonych danych. Na przykład, jeśli masz następującą tablicę:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
Jeśli chcesz uniknąć zapętlania się przez właściwość otherData, ponieważ wartość, którą zamierzasz agregować, nie jest zagnieżdżona tak głęboko, możesz ustawić wartość shallow na true.