【问题标题】:Best way to merge two objects and sum the values of same key?合并两个对象并对相同键的值求和的最佳方法?
【发布时间】:2017-08-28 06:55:54
【问题描述】:

我有两个类似的对象:

let data = [[
  {
    10: {key1: 1, key2: 2, key3: 3},
    11: {key1: 1, key2: 2, key3: 3},
    12: {key1: 1, key2: 2, key3: 3},
    },
  {},
  {}
],
[
  {
    10: {key1: 1, key2: 2, key3: 3},
    11: {key1: 1, key2: 2, key3: 3},
    12: {key1: 1, key2: 2, key3: 3},
    },
  {},
  {}
]]

我想创建一个新对象并对每个键的每个值求和。像这样:

let newData = [
      {
        10: {key1: 2, key2: 4, key3: 6},
        11: {key1: 2, key2: 4, key3: 6},
        12: {key1: 2, key2: 4, key3: 6},
        },
      {},
      {}
    ]

每个对象都包含三个对象。在这三个对象中,有 45 个键,每个对象都有一个具有三个键/值的对象。

我找不到任何好的解决方案来汇总每个值。

我目前的解决方案是我首先循环通过data:

let count = 0;
let count2 = 0;
for(let ob of data){
     for(let child in ob[0]){
          keyOne = ob[0][child].keyOne;
          keyTwo = ob[0][child].keyTwo;
          keyThree = ob[0][child].keyThree;
          keyFour = ob[0][child].keyFour;
          if(count < 45) {
               newData[0][count].keyOne += keyOne;
               newData[0][count].keyTwo += gkeyTwop;
               newData[0][count].keyThree += keyThree;
               newData[0][count].keyFour += keyFour;
          } else {
               newData[0][count2].keyOne += keyOne;
               newData[0][count2].keyTwo += keyTwo;
               newData[0][count2].keyThree += keyThree;
               newData[0][count2].keyFour += keyFour;
               count2++;

          }
          count++;
     }

在最坏的情况下,数据得到三个对象,每个对象有 45 个键。然后我必须这样做三遍。这似乎真的很糟糕。一定会有更好的办法。提示?

【问题讨论】:

  • 如果您重复执行此操作,最好将各个对象的总和分开并仅添加总和而不是整个循环。
  • 1+ 因为不称它们为“JSON 对象”;)

标签: javascript node.js performance javascript-objects


【解决方案1】:

这是reduce() 和少数forEach() 循环的解决方案,因为您还需要循环嵌套对象。

var data = [[{"10":{"key1":1,"key2":2,"key3":3},"11":{"key1":1,"key2":2,"key3":3},"12":{"key1":1,"key2":2,"key3":3}},{},{}],[{"10":{"key1":1,"key2":2,"key3":3},"11":{"key1":1,"key2":2,"key3":3},"12":{"key1":1,"key2":2,"key3":3}},{},{}]]

var result = data.reduce(function(r, e, i) {
  if (i == 0) r = r.concat(e)
  else  {
  e.forEach(function(a, j) {
       Object.keys(a).forEach(function(key) {
          if (!r[j][key]) r[j][key] = a[key]
          else {
            Object.keys(a[key]).forEach(function(k) {
              r[j][key][k] += a[key][k]
            })
          }
      })
    })
  }
  return r;
}, [])

console.log(result)

【讨论】:

    【解决方案2】:

    您可以使用Array#reduce 并在添加值后映射内部数组的值。

    var data = [[{ 10: { key1: 1, key2: 2, key3: 3 }, 11: { key1: 1, key2: 2, key3: 3 }, 12: { key1: 1, key2: 2, key3: 3 }, }, {}, {}], [{ 10: { key1: 1, key2: 2, key3: 3 }, 11: { key1: 1, key2: 2, key3: 3 }, 12: { key1: 1, key2: 2, key3: 3 }, }, {}, {}]],
        result = data.reduce((a, b) => 
            a.map((v, i) =>
                (Object.keys(b[i]).forEach(k =>
                    Object.keys(b[i][k]).forEach(l => 
                        v[k][l] = (v[k][l] || 0) + b[i][k][l]))
                , v)
            )
        );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 有没有办法不用逗号来做到这一点?
    • 总有办法,但比逗号复杂,因为要更改对象并返回。结果可能比实际更难看。
    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2021-10-09
    • 2020-01-19
    • 2017-09-28
    相关资源
    最近更新 更多