Sum all data in array of objects into new array of objects

后端 未结 14 892
借酒劲吻你
借酒劲吻你 2020-12-29 03:32

I have an array of objects that looks like this:

var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}]
         


        
相关标签:
14条回答
  • 2020-12-29 04:11

    map the object and calculate the sum and store it in another.

    var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}];
    var result = [];
    var sum = 0;
    var costsum = 0;
    data.map(function(item, key){
      var cost = item;
      //nsole.log(cost);
      sum = sum + cost.costOfAirtickets;
      costsum = costsum + cost.costOfHotel;
    
    });
    
    result = [{costOfAirtickets:sum, costOfHotel:costsum}];
    
    console.log(result);

    0 讨论(0)
  • 2020-12-29 04:14

    You could reduce the array by taking an object for summing.

    var data = [{ costOfAirtickets: 2500, costOfHotel: 1200 }, { costOfAirtickets: 1500, costOfHotel: 1000 }],
        keys = ['costOfAirtickets', 'costOfHotel'],
        sum = data.reduce((r, o) => {
            keys.forEach(k => r[k] += o[k]);
            return r;
        }, Object.assign(...keys.map(k => ({ [k]: 0 }))));
    
    console.log(sum);

    0 讨论(0)
  • 2020-12-29 04:15

    Try using reduce only as in the below snippet. Try avoiding multiple iterations. Hope the below snippet helps!

    var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}]
    
    var total = data.reduce(function (result,value,key) {
    result['costOfAirtickets'] = result['costOfAirtickets']  + value['costOfAirtickets'];
    result['costOfHotel'] = result['costOfHotel']  + value['costOfHotel'];
    
    return result},{costOfAirtickets:0,costOfHotel:0});
    
    console.log(total)

    0 讨论(0)
  • 2020-12-29 04:16

    Another solution would be to use Map (not Array.prototype.map) as it has several notable differences compared to objects:

    var data = [{
      costOfAirtickets: 2500,
      costOfHotel: 1200
    }, {
      costOfAirtickets: 1500,
      costOfHotel: 1000
    }]
    
    let sums = data.reduce((collection,rcd)=>{
      Object.entries(rcd).forEach(([key,value])=>{
          let sum = collection.get(key) || 0
          collection.set(key, sum + +value)
      })
      return collection
    }, new Map())
    
    console.log(...sums.entries())

    Explanation

    Outer loop

    The above first iterates over your data array using the reduce method. Each object within that I'll be referring to as a record -- distinguished in the code via the variable, rcd.

    Each iteration of reduce returns a value which is passed as the first argument to the next iteration of the loop. In this case, the parameter collection holds that argument, which is your set of sums.

    Inner loop

    Within the reduce loop, each key/value pair of the record is iterated over using forEach. To get the key/value pair the Object.entries method is used. Using array destructuring these arguments can be directly assigned to the respective variables, key and value

    Retrieving/Setting values

    Unlike a primitive object, Map has its own methods for getting and setting its entries using get() and set(). So first retrieve the previous sum using get(), if it's not set then default to 0, which is what the || 0 does. At that point, you can assume the previous sum is at least 0 or greater and add the current key's value onto it.

    Alternatives to Map

    If you find Map is a bit heavy-handed, you may also use a similar object such as Set, which has many of the same methods (except the get()), or you could also use a primitive object (i.e. {}).

    0 讨论(0)
  • 2020-12-29 04:16

    You can use a simple forEach() loop for that:

    var data = [{costOfAirtickets: 2500, costOfHotel: 1200},{costOfAirtickets: 1500, costOfHotel: 1000}];
    var res = [];
    var tempObj = {};
    data.forEach(({costOfAirtickets, costOfHotel}) => {
      tempObj['costOfAirtickets'] = (tempObj['costOfAirtickets'] || 0) + costOfAirtickets;
      tempObj['costOfHotel'] = (tempObj['costOfHotel'] || 0) + costOfHotel;
     });
    res.push(tempObj);
    console.log(res);

    0 讨论(0)
  • 2020-12-29 04:18

    To create a resultant / reduced value, you should use .reduce() method instead of .map():

    let data = [
      {costOfAirtickets: 2500, costOfHotel: 1200},
      {costOfAirtickets: 1500, costOfHotel: 1000}
    ];
    
    let result = data.reduce(
      (a, c) => (Object.keys(c).forEach(k => (a[k] = (a[k] || 0) + c[k])), a), {}
    );
    
    console.log(result);

    0 讨论(0)
提交回复
热议问题