简体   繁体   中英

How to add object properties of an array and update it?

I have an array of objects and i want to update Total value by adding months

var arrObj=[
  {name:"ABC",Jan:0,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0},
    {name:"BCD",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0},
   {name:"DEF",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0},
   {name:"FGH",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}
]

I am updating the value using loops and it is working also but is there any best way to put this?

var len=arrObj.length;
var Total=0;
for(var i=0;i<len;i++){
arrObj[i].Total= +arrObj[i].Jan + +arrObj[i].Feb + +arrObj[i].Mar+ +arrObj[i].Apr+ +arrObj[i].May+ +arrObj[i].Jun+ +arrObj[i].Jul+ +arrObj[i].Aug+ +arrObj[i].Sep+ +arrObj[i].Oct+ +arrObj[i].Nov+ +arrObj[i].Dec;
}
console.log(arrObj)

 var arrObj=[ {name:"ABC",Jan:0,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"BCD",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"DEF",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"FGH",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0} ] var len=arrObj.length; var Total=0; for(var i=0;i<len;i++){ arrObj[i].Total= +arrObj[i].Jan + +arrObj[i].Feb + +arrObj[i].Mar+ +arrObj[i].Apr+ +arrObj[i].May+ +arrObj[i].Jun+ +arrObj[i].Jul+ +arrObj[i].Aug+ +arrObj[i].Sep+ +arrObj[i].Oct+ +arrObj[i].Nov+ +arrObj[i].Dec; } console.log(arrObj)

You can define a function which gets the total from each object

const getTotal = obj => {
    let total = 0;
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    months.forEach(month => total += obj[month]);
    return total;
}

And then use it like

arrObj.forEach(obj => obj.total = getTotal(obj));

I would do something like below.

  1. Loop through array elements
  2. Filter out the unwanted keys
  3. Reduce the remaining keys to get the total

 arrObj.forEach((element) => { element.Total = Object.keys(element). filter(key => key.== "name" && key,== "Total"), reduce((acc,key) => acc + element[key], 0) } )

You could use a loop and exclude the fields name and Total . But it would be harder to read.

 var arrObj=[ {name:"ABC",Jan:0,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"BCD",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"DEF",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0}, {name:"FGH",Jan:10,Feb:20,Mar:30,Apr:40,May:50,Jun:70,Jul:80,Aug:90,Sep:100,Oct:110,Nov:120,Dec:130,Total:0} ] for(let i in arrObj){ for(let eli in arrObj[i]){ if(eli.= "Total" && eli;= "name"){ arrObj[i].Total += arrObj[i][eli]; } } } console.log(arrObj);

The best way would be to have an Array inside the JS-Object and use the reduce function. But I may assume that this won't apply to your use-case.

 var arrObj=[ {name:"BCD",months:[10,20,30,40,50,70,80,90,100,110,120,130],Total:0}, {name:"DEF",months: [10,20,30,40,50,70,80,90,100,110,120,130],Total:0} ]; arrObj.forEach((e,i) => { arrObj[i].Total = e.months.reduce((a,b) => a+b); }); console.log(arrObj);

It can be done using reduce method:

var arrObj = [
        { name: "ABC", Jan: 0, Feb: 20, Mar: 30, Apr: 40, May: 50, Jun: 70, Jul: 80, Aug: 90, Sep: 100, Oct: 110, Nov: 120, Dec: 130, Total: 0 },
        { name: "BCD", Jan: 10, Feb: 20, Mar: 30, Apr: 40, May: 50, Jun: 70, Jul: 80, Aug: 90, Sep: 100, Oct: 110, Nov: 120, Dec: 130, Total: 0 },
        { name: "DEF", Jan: 10, Feb: 20, Mar: 30, Apr: 40, May: 50, Jun: 70, Jul: 80, Aug: 90, Sep: 100, Oct: 110, Nov: 120, Dec: 130, Total: 0 },
        { name: "FGH", Jan: 10, Feb: 20, Mar: 30, Apr: 40, May: 50, Jun: 70, Jul: 80, Aug: 90, Sep: 100, Oct: 110, Nov: 120, Dec: 130, Total: 0 }
    ];

arrObj.forEach(element => {
    let totalSum = Object.keys(element)
        .reduce((sum, key) =>{               
             return sum += parseFloat(element[key]) || 0
        }, 0);
    element.Total = totalSum;
});

console.log(arrObj);

One can define a getter property of an object where the total gets computed on every change of the properties that depends on.

In es6 one can use class and get properties to achieve this.

 Class MonthTotal {
    public Jan;
    public Feb;
    public MonthTotal(data) {
       this.Jan = data.Jan;
       this.Feb = data.Feb;
    }
    get Total() {
      return this.Jan + this.Feb;
    }
 }
 const monthData = new MonthTotal({ Jan: 10, Feb: 20});
 console.log(monthData.total); // logs :: 30

In es5 we can leverage with a simple functional getter properties call

var monthData = { 
  name:"ABC",
  Jan:0,
  Feb:20,
  Mar:30
  get total() {
    return this.Jan + this.Feb + this.Mar;
  }
}

console.log(monthData.total); // logs :: 30

I'm assuming you are new to programming and I'm also assuming you have complete control over the data structure so if you already know this I apologize.

There is this concept called data integrity . There are a few rules to this but the most important for the beginner to understand is what is the meaning of the data. In this case do you intact or change the data or do you just read from it?

With totals you don't interact with it directly it should be a calculation of other values and the only way to change it is by changing other values.

In JavaScript, there is the Getter which solves this problem.

Looks like this.

const obj = {
  value: 3,
  get doubleValue () {
    return this.value * 2
  }
}
obj.doubleValue // 6

In your case, you can have something like this.

{
  get Total () {
    return ...calculation
  }
}

Here is a working example

{
  name:"ABC",
  Jan:0,
  Feb:20,
  Mar:30,
  Apr:40,
  May:50,
  Jun:70,
  Jul:80,
  Aug:90,
  Sep:100,
  Oct:110,
  Nov:120,
  Dec:130,
  get Total () {
    const keys = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    let sum = 0;
    keys.forEach((key) => {
      sum += this[key]
    })
    return sum
  }
}

So If you change any of the value then call Total it will automatically update.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM