但是,如果您需要更强大和更灵活的解决方案,那么我对聚会有点迟钝,那么这是我的贡献。如果您只想对嵌套对象/数组组合中的特定属性求和,以及执行其他聚合方法,那么这是我在 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 = 对象或数组
属性= 您希望在聚合上执行
聚合方法的嵌套对象/数组中的属性= 聚合方法(sum、min、max 或 count)
shallow = 可以设置为 true/ false 或数值
depth = 应为 null 或未定义(用于跟踪后续递归回调)
如果您知道不需要搜索深度嵌套的数据,则可以使用 Shallow 来提高性能。例如,如果您有以下数组:
[
{
id: 1,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 2,
otherData: { ... },
valueToBeTotaled: ?
},
{
id: 3,
otherData: { ... },
valueToBeTotaled: ?
},
...
]
如果您想避免循环遍历 otherData 属性,因为您要聚合的值没有嵌套那么深,您可以将 shallow 设置为 true。