我有一个由data组成的数组,其中每个数据都有多个subData,
var res = [
{
data1:{subData1:56, subData2:0, subData3:45},
data2:{subData2:565, subData3:67, subData4:45},
data3:{subData1:45, subData3:0},
data4:{subData1:32, subData2:0, subData3:47},
data5:{subData1:107, subData2:34, subData3:65},
data6:{subData3:123, subData4:43},
data7:{subData1:432, subData2:67, subData3:78},
data8:{subData4:23, subData5:432, subData6:654},
}
];
我需要获取数组中每个subData的总和,我已经找到了解决方案,但是如何减少代码。请找到以下代码以解决问题,并提出一种更好的优化方法。我也在使用下划线js。
var res = [
{
data1:{subData1:56, subData2:0, subData3:45},
data2:{subData2:565, subData3:67, subData4:45},
data3:{subData1:45, subData3:0},
data4:{subData1:32, subData2:0, subData3:47},
data5:{subData1:107, subData2:34, subData3:65},
data6:{subData3:123, subData4:43},
data7:{subData1:432, subData2:67, subData3:78},
data8:{subData4:23, subData5:432, subData6:654},
}
];
var values = Object.values(res[0])
var arrayOfItems = [];
var sums = {};
values.map(obj => Object.keys(obj)).map(item => {item.map(subItem => arrayOfItems.push(subItem))})
arrayOfItems = _.uniq(arrayOfItems)
_.each(values, function (item) {
_.each(arrayOfItems, function (color) {
if(sums.hasOwnProperty(color)){
sums[color] = sums[color] + ( item[color] ? item[color] : 0 )
}else{
sums[color] = 0 + (item[color] ? item[color] : 0)
}
});
});
var arrOfSubDatasTotal = Object.keys(sums).map(item => ({name:item, total:sums[item]}))
var totalOfSubDatas = Object.values(sums).reduce((a,b) => a + b)
console.log("array Of SubDatas Total =>", arrOfSubDatasTotal)
console.log("total Of SubDatas =>", totalOfSubDatas)
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
答案 0 :(得分:0)
请尝试使用Array.reduce,Array.forEach,Array.map,Object.values,Object.entries
逻辑
创建一个键为subData{number}
,值为其值之和的对象。
要创建对象,请使用Array.reduce
遍历数组中的每个对象,然后使用Object.values
获取对象中的所有值。使用Array.forEach
遍历每个值,然后对于每个对象,使用Object.entries
添加/更新中间对象中的条目(减少累加器)。
在创建对象时,对所有值求和以创建所有total
中的subData's
。最后使用object
将array
转换为Object.entries
,然后使用Array.map
将其转换为所需的格式。
var res = [{data1:{subData1:56, subData2:0, subData3:45},data2:{subData2:565, subData3:67, subData4:45},data3:{subData1:45, subData3:0},data4:{subData1:32, subData2:0, subData3:47},data5:{subData1:107, subData2:34, subData3:65},data6:{subData3:123, subData4:43},data7:{subData1:432, subData2:67, subData3:78},data8:{subData4:23, subData5:432, subData6:654}}];
let total = 0;
let result = Object.entries(
res.reduce((a,c) => {
Object.values(c).forEach(
o => Object.entries(o).forEach(([k,v]) => {
a[k] = (a[k] || 0) + v;
total += v;
})
);
return a;
}, {})
).map(([k,v]) => ({name: k, total : v}));
console.log(result);
console.log(total);
答案 1 :(得分:0)
您可以使用Sum
Monoid浏览该列表
import propOr from 'crocks/helpers/propOr'
import curry from 'crocks/helpers/curry'
import mreduceMap from 'crocks/helpers/mreduceMap'
import Sum from 'crocks/Sum'
var res = [{
data1:{subData1:56, subData2:0, subData3:45},
data2:{subData2:565, subData3:67, subData4:45},
data3:{subData1:45, subData3:0},
data4:{subData1:32, subData2:0, subData3:47},
data5:{subData1:107, subData2:34, subData3:65},
data6:{subData3:123, subData4:43},
data7:{subData1:432, subData2:67, subData3:78},
data8:{subData4:23, subData5:432, subData6:654},
}];
const data = Object.values(res[0])
const getSubData = i => propOr(0, 'subData' + i)
const getDataSum = curry(i => mreduceMap(Sum, getSubData(i)))
console.log(getDataSum(1, data))
// 672 - the sum of all subData1 properties in the list
答案 2 :(得分:0)
您可以在纯JS中尝试此操作。希望对您有所帮助。
const res = [{
data1:{subData1:56, subData2:0, subData3:45},
data2:{subData2:565, subData3:67, subData4:45},
data3:{subData1:45, subData3:0},
data4:{subData1:32, subData2:0, subData3:47},
data5:{subData1:107, subData2:34, subData3:65},
data6:{subData3:123, subData4:43},
data7:{subData1:432, subData2:67, subData3:78},
data8:{subData4:23, subData5:432, subData6:654},
}];
const sums = {};
// For each item on your array
res.forEach((item) => {
Object.keys(item).forEach((key) => {
Object.keys(item[key]).forEach((sub) => {
// Initialize its position on the sum object
if (!sums[sub]) sums[sub] = { sum: 0, name: sub };
sums[sub].sum += item[key][sub];
});
});
});
// Get the total of the subData
const total = Object.values(sums).reduce((acc, val) => acc += val.sum, 0.0);
console.log('Sums', Object.values(sums));
console.log('Total', total);