Can not add row sum and column sum from array of objects using Javascript

Viewed 273

I have some array of objects and I need to calculate the total value of each row and total values of each column and finally I will add new key to each object using Javascript. I am explaining my code below.

my input is like below.

let book_data= [ 
    { BranchName: 'Deeksha, Thanisandra, Bengaluru',
        Uniform: 2,
        Shoes: 1,
        Accessories: 1,
        Books: 5,
     },
      { BranchName: 'Deeksha, Thanisandra, Bengaluru',
        Uniform: 2,
        Shoes: 3,
        Accessories: 4,
        Books: 5,
      }
    ]

Here I need to add one more column i.e-Grand total to each row and this should contain the sum of all key value rather than BranchName. Similarly again I need to append one more new record as last row and it should contant total value of each column. I am giving my sample output below.

enter image description here

I am explaining my code below.

for(let i=0; i<book_data.length; i++) {
        let grandRowTotal = 0;
        for(let key in book_data[i]) {
            if(key !== 'BranchName') {
                console.log('key', book_data[i][key]);
                grandRowTotal += parseInt(book_data[i][key]);
            }
        }
        book_data[i]['Grand Total'] = grandRowTotal;
        console.log('grandRowTotal', book_data[i],book_data);

    }

As per my code its not giving the expected result. I need here the sum of each row and column value as per my sample output above.

3 Answers

I have created an extra array to keep track of the columns.

  1. Basically what I do below is loop through the original array of book_data.
  2. In each iteration i also loop through the columns data for each book.
  3. This allows me to both modify the GrandTotal object and the RowTotal data

In your question you have two loops to loop through the book data. This is not necessary. Since its an array you can simply use the forEach method on an array.

Hope this helps :)

    var book_data = [{
        BranchName: 'Deeksha, Thanisandra, Bengaluru',
        Uniform: 2,
        Shoes: 1,
        Accessories: 1,
        Books: 5,
      },
      {
        BranchName: 'Deeksha, Thanisandra, Bengaluru',
        Uniform: 2,
        Shoes: 3,
        Accessories: 4,
        Books: 5,
      }
    ];


    var ColumnTotals = {
      BranchName: 'Grand Total'
    };

    var columns = ['Uniform', 'Shoes', 'Accessories', 'Books'];

    book_data.forEach(b => {
      let rowTotal = 0;
      columns.forEach(i => {
        if (b[i] === undefined) {
          return;
        }

        ColumnTotals[i] = ColumnTotals[i] || 0;
        ColumnTotals[i] += b[i];
        rowTotal += b[i];
      })
      b.RowTotal = rowTotal;
    });

    // Calculate RowTotal for ColumnsTotals
    columns.forEach(i => {
      ColumnTotals.RowTotal = ColumnTotals.RowTotal || 0;
      ColumnTotals.RowTotal += ColumnTotals[i];
    })

    // Adding ColumnTotals to the Array
    book_data.push(ColumnTotals);

    console.log('BookData', book_data);
    console.table(book_data);

you need an object to keep the summary data, I change your code to this.
the fields of summary object will be added dynamically and you don't need to declare a variable for each field.

It has two advantages :
1. this is beneficial when each row has different fields.
2. when in the future a field like car: 10 is added to the data you don't need to change your code.

let book_data = [
  {
    BranchName: 'Deeksha, Thanisandra, Bengaluru',
    Uniform: 2,
    Shoes: 1,
    Accessories: 1,
    Books: 5,
  },
  {
    BranchName: 'Deeksha, Thanisandra, Bengaluru',
    Uniform: 2,
    Shoes: 3,
    Accessories: 4,
    Books: 5,
  },
]

// the last row that show the summary
const summary = { BranchName: 'Grand Total', GrandTotal: 0 }
for (let i = 0; i < book_data.length; i++) {
  let grandRowTotal = 0
  for (let key in book_data[i]) {
    if (key !== 'BranchName') {
      const amount = parseInt(book_data[i][key])
      grandRowTotal += amount
      // calc the summary
      if (summary[key] === undefined) {
        summary[key] = 0
      }
      summary[key] += amount
      summary['GrandTotal'] += amount
    }
  }
  book_data[i]['GrandTotal'] = grandRowTotal
}
book_data.push(summary)

console.log(book_data)

Your problem is that book_data[i] is an object instead of an array, so you can't make use of for.

But, you can use Object.keys() to get an array of object keys, then iterate like you are normally doing:

let key in Object.keys(book_data[i]) // instead of 'let key in book_data[i]' in your for

This should be enough to solve it

Related