简体   繁体   中英

loop through the objects inside the array and sum it up

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM