如何添加数组的对象属性并更新它?

时间:2019-09-24 13:11:30

标签: javascript arrays

我有一个对象数组,我想通过增加月份来更新Total的值

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}
]

我正在使用loops更新值,它也可以工作,但是有什么最好的方法吗?

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)

6 个答案:

答案 0 :(得分:1)

您可以定义一个从每个对象获取总计的函数

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;
}

然后像使用它

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

答案 1 :(得分:0)

我会做下面的事情。

  1. 遍历数组元素
  2. 过滤掉不需要的密钥
  3. 减少其余键以获得总数

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

答案 2 :(得分:0)

您可以使用循环并排除字段nameTotal。但这很难阅读。

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);

最好的方法是在JS对象中包含一个数组并使用reduce函数。但我可能会认为这不适用于您的用例。

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);

答案 3 :(得分:0)

可以使用reduce方法完成

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);

答案 4 :(得分:0)

可以定义对象获取器属性,其中总计将在每个上进行计算更改属性

es6 中,可以使用 class 获取属性来实现这一目标。

 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

es5 中,我们可以通过简单的功能getter属性调用来利用

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

答案 5 :(得分:0)

我假设您是编程新手,并且还假设您完全控制数据结构,因此,如果您已经知道这一点,我深表歉意。

有一个称为data integrity的概念。有一些规则,但是对于初学者来说最重要的是数据的含义。在这种情况下,您是完好无损还是更改了数据,还是只是从中读取数据?

对于总计,您不直接与之交互,它应该是其他值的计算,并且更改它的唯一方法是更改​​其他值。

在JavaScript中,有Getter可以解决此问题。

看起来像这样。

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

就您而言,您可以拥有类似的东西。

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

这是一个可行的例子

{
  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
  }
}

因此,如果您更改任何值,则调用Total将会自动更新。