遍历数组内部的对象并将其求和

时间:2018-09-26 12:05:01

标签: javascript

我有一个由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>

3 个答案:

答案 0 :(得分:0)

请尝试使用Array.reduceArray.forEachArray.mapObject.valuesObject.entries

逻辑

创建一个键为subData{number},值为其值之和的对象。

要创建对象,请使用Array.reduce遍历数组中的每个对象,然后使用Object.values获取对象中的所有值。使用Array.forEach遍历每个值,然后对于每个对象,使用Object.entries添加/更新中间对象中的条目(减少累加器)。

在创建对象时,对所有值求和以创建所有total中的subData's。最后使用objectarray转换为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);