Ich bin etwas verspätet gegenüber der Party, aber wenn Sie eine robustere und flexiblere Lösung benötigen, dann ist hier mein Beitrag. Wenn Sie nur eine bestimmte Eigenschaft in einer Kombination aus verschachteltem Objekt und Array summieren und andere Aggregatmethoden ausführen möchten, ist hier eine kleine Funktion, die ich für ein React-Projekt verwendet habe:
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;
}
Es ist rekursiv, nicht ES6, und es sollte in den meisten semi-modernen Browsern funktionieren. Sie verwenden es so:
const onlineCount = aggregateProperty(this.props.contacts, 'online', 'count');
Parameteraufschlüsselung:
obj = entweder ein Objekt oder eine Array-
Eigenschaft = die Eigenschaft innerhalb der verschachtelten Objekte / Arrays, für die Sie die Aggregatmethode für
Aggregat ausführen möchten = die Aggregatmethode (Summe, Min, Max oder Anzahl)
flach = kann entweder auf true / gesetzt werden false oder eine numerische
Werttiefe = sollte null oder undefiniert bleiben (wird verwendet, um die nachfolgenden rekursiven Rückrufe zu verfolgen).
Flach kann verwendet werden, um die Leistung zu verbessern, wenn Sie wissen, dass Sie keine tief verschachtelten Daten durchsuchen müssen. Zum Beispiel, wenn Sie das folgende Array hatten:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
Wenn Sie vermeiden möchten, die Eigenschaft otherData zu durchlaufen, da der Wert, den Sie aggregieren möchten, nicht so tief verschachtelt ist, können Sie flach auf true setzen.