I have a an array consist of datas , where each datas has multiple subDatas,
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},
}
];
i need to get the sum of each subDatas in an array, i have figured out the solution but how can i reduce the code . Please find the below code for solving and suggest a better optimized way. I am using underscore js too.
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>
Try following using Array.reduce , Array.forEach , Array.map , Object.values , Object.entries
LOGIC
Create an object with keys as subData{number}
and value as the sum of its values .
To create object, use Array.reduce
to iterate over each object in array and then Object.values
to get all the values in the object. Iterate over each value using Array.forEach
and then for each object, use Object.entries
to add / update the entry in intermediate object ( reduce accumulator ).
While creating the object, sum all the values to create the total
of all the subData's
. Finally transform object
to array
using Object.entries
and use Array.map
to convert it into the desired format.
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);
You can use the Sum
monoid to whip through that list
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
You can try this in pure JS. Hope it helps.
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.