Better way to sum a property value in an array

后端 未结 16 1453
遥遥无期
遥遥无期 2020-11-22 02:41

I have something like this:

$scope.traveler = [
            {  description: \'Senior\', Amount: 50},
            {  description: \'Senior\', Amount: 50},
             


        
相关标签:
16条回答
  • 2020-11-22 03:11

    From array of objects

    function getSum(array, column)
      let values = array.map((item) => parseInt(item[column]) || 0)
      return values.reduce((a, b) => a + b)
    }
    
    foo = [
      { a: 1, b: "" },
      { a: null, b: 2 },
      { a: 1, b: 2 },
      { a: 1, b: 2 },
    ]
    
    getSum(foo, a) == 3
    getSum(foo, b) == 6
    
    0 讨论(0)
  • 2020-11-22 03:12

    I'm not sure this has been mentioned yet. But there is a lodash function for that. Snippet below where value is your attribute to sum is 'value'.

    _.sumBy(objects, 'value');
    _.sumBy(objects, function(o) { return o.value; });
    

    Both will work.

    0 讨论(0)
  • 2020-11-22 03:14

    Updated Answer

    Due to all the downsides of adding a function to the Array prototype, I am updating this answer to provide an alternative that keeps the syntax similar to the syntax originally requested in the question.

    class TravellerCollection extends Array {
        sum(key) {
            return this.reduce((a, b) => a + (b[key] || 0), 0);
        }
    }
    const traveler = new TravellerCollection(...[
        {  description: 'Senior', Amount: 50},
        {  description: 'Senior', Amount: 50},
        {  description: 'Adult', Amount: 75},
        {  description: 'Child', Amount: 35},
        {  description: 'Infant', Amount: 25 },
    ]);
    
    console.log(traveler.sum('Amount')); //~> 235
    

    Original Answer

    Since it is an array you could add a function to the Array prototype.

    traveler = [
        {  description: 'Senior', Amount: 50},
        {  description: 'Senior', Amount: 50},
        {  description: 'Adult', Amount: 75},
        {  description: 'Child', Amount: 35},
        {  description: 'Infant', Amount: 25 },
    ];
    
    Array.prototype.sum = function (prop) {
        var total = 0
        for ( var i = 0, _len = this.length; i < _len; i++ ) {
            total += this[i][prop]
        }
        return total
    }
    
    console.log(traveler.sum("Amount"))
    

    The Fiddle: http://jsfiddle.net/9BAmj/

    0 讨论(0)
  • 2020-11-22 03:15

    I was already using jquery. But I think its intuitive enough to just have:

    var total_amount = 0; 
    $.each(traveler, function( i, v ) { total_amount += v.Amount ; });
    

    This is basically just a short-hand version of @akhouri's answer.

    0 讨论(0)
  • 2020-11-22 03:16

    Just another take, this is what native JavaScript functions Map and Reduce were built for (Map and Reduce are powerhouses in many languages).

    var traveler = [{description: 'Senior', Amount: 50},
                    {description: 'Senior', Amount: 50},
                    {description: 'Adult', Amount: 75},
                    {description: 'Child', Amount: 35},
                    {description: 'Infant', Amount: 25}];
    
    function amount(item){
      return item.Amount;
    }
    
    function sum(prev, next){
      return prev + next;
    }
    
    traveler.map(amount).reduce(sum);
    // => 235;
    
    // or use arrow functions
    traveler.map(item => item.Amount).reduce((prev, next) => prev + next);
    

    Note: by making separate smaller functions we get the ability to use them again.

    // Example of reuse.
    // Get only Amounts greater than 0;
    
    // Also, while using Javascript, stick with camelCase.
    // If you do decide to go against the standards, 
    // then maintain your decision with all keys as in...
    
    // { description: 'Senior', Amount: 50 }
    
    // would be
    
    // { Description: 'Senior', Amount: 50 };
    
    var travelers = [{description: 'Senior', amount: 50},
                    {description: 'Senior', amount: 50},
                    {description: 'Adult', amount: 75},
                    {description: 'Child', amount: 35},
                    {description: 'Infant', amount: 0 }];
    
    // Directly above Travelers array I changed "Amount" to "amount" to match standards.
    
    function amount(item){
      return item.amount;
    }
    
    travelers.filter(amount);
    // => [{description: 'Senior', amount: 50},
    //     {description: 'Senior', amount: 50},
    //     {description: 'Adult', amount: 75},
    //     {description: 'Child', amount: 35}];
    //     Does not include "Infant" as 0 is falsey.
    
    0 讨论(0)
  • 2020-11-22 03:21

    Use reduce with destructuring to sum Amount:

    const traveler = [
      { description: 'Senior', Amount: 50 },
      { description: 'Senior', Amount: 50 },
      { description: 'Adult', Amount: 75 },
      { description: 'Child', Amount: 35 },
      { description: 'Infant', Amount: 25 },
    ];
    
    console.log(traveler.reduce((n, {Amount}) => n + Amount, 0))
    
    0 讨论(0)
提交回复
热议问题