javascriptarraysprototype-programming

Better way to sum a property value in an array


I have something like this:

$scope.traveler = [
            {  description: 'Senior', Amount: 50},
            {  description: 'Senior', Amount: 50},
            {  description: 'Adult', Amount: 75},
            {  description: 'Child', Amount: 35},
            {  description: 'Infant', Amount: 25 },
];

Now to have a total Amount of this array I'm doing something like this:

$scope.totalAmount = function(){
       var total = 0;
       for (var i = 0; i < $scope.traveler.length; i++) {
              total = total + $scope.traveler[i].Amount;
            }
       return total;
}

It's easy when is only one array, but I have others arrays with a different property name that I would like to sum.

I would be happier If I could do something like this:

$scope.traveler.Sum({ Amount });

But I don't know how to go through this in a way that I could reuse it in the future like this:

$scope.someArray.Sum({ someProperty });

Solution

  • 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"))