【问题标题】:Merge objects of Array by key name通过键名合并 Array 的对象
【发布时间】:2020-01-17 16:10:12
【问题描述】:

我想转这种数组:

let myArray = [
    { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
    { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
    { even: [16,18], odd: [15,15,17] }
]

进入:

myArray = [
    { even: [2,4,6,4,6,8,16,18] }, 
    { odd: [1,3,5,7,7,9,11,13,15,15,17] }, 
    { decimals: [3.14, 12.8, 111.1] },
]

也许我应该为此使用“减少”,但我根本不熟悉该功能。如果有人能告诉我好的路径

【问题讨论】:

  • 你是只有 3 个键还是可以有更多键
  • 如果你的最终输出是一个对象而不是一个数组,可以说你会更好。
  • @ShubhamKhatri,可以有更多的键!

标签: javascript arrays merge reduce


【解决方案1】:

也许我可以给你一个更短更聪明的答案:

myArray.reduce((acc, obj = {}) => ({
  even: [...acc.even, ...(obj.even || [])],
  odd: [...acc.odd, ...(obj.odd || [])],
  decimals: [...acc.decimals, ...(obj.decimals || [])],
}), { even: [], odd: [], decimals: []})

Reduce 非常强大,您可以在许多用例中使用:当您希望 .filter().map() 在同一个数组上时,可以通过一次 .reduce() 调用对其进行优化。

在动画中查看.reduce()https://twitter.com/jacobmparis/status/1213887721799913479

顺便说一句:此解决方案使用对象作为输出而不是数组

【讨论】:

  • 是否存在更多键?这不是一个通用的解决方案
  • 在我的情况下会有更多的键(对不起,我应该更精确)
【解决方案2】:

我想这种格式的结果会更好

myArray = {
    even: [2,4,6,4,6,8,16,18], 
    odd: [1,3,5,7,7,9,11,13,15,15,17], 
    decimals: [3.14, 12.8, 111.1],
}

下面的代码就是这样做的。

const newObj = myArray.reduce((prev, item) => {
    for (key in item) {
        prev[key] = [...(prev[key] || []), ...item[key]]
    }

    return prev
}, {})

【讨论】:

    【解决方案3】:

    将数组简化为累加器对象 - 通过 Object.entries() 将原始数组中的每个对象转换为条目,使用 Array.forEach() 迭代条目 ([key, values]),并将值与键的先前值连接。

    将生成的对象再次转换为条目,并映射到对象数组。

    const myArray = [
      { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
      { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
      { even: [16,18], odd: [15,15,17] }
    ]
    
    const result = Object.entries( // convert the accumulator to entries
        myArray.reduce((r, o) => {
          Object.entries(o) // convert object to entries
            .forEach(([k, v]) => r[k] = [...(r[k] || []), ...v]) // add the values to the respective key in the accumulator
    
          return r
        }, {})
      )
      .map(([k, v]) => ({ [k]: v })) // map to objects
      
    console.log(result)

    【讨论】:

      【解决方案4】:

      Reduce 将第一个参数作为方法,第二个作为起始值。第一个参数,方法,将接收两个值,第一个是到目前为止的累积值,它将等于第一次作为第二个参数传递的基值。函数的第二个参数是数组中的当前值,因为函数将被调用以遍历数组的每个值,并将这两个值作为参数传递给方法,即 reduce 的第一个参数。此外,reduce 函数的第一个参数,方法,应该在最后返回一个值,该值将作为第一个参数提供给将作为最终累加值的方法。一旦循环结束,reduce 将返回最终的累加值。

      试试下面的代码 sn-p。它可能会帮助你。

      function mergeArray(arr) {
        // Creating the JSON from the array with all the keys and merged data.
        const json = arr.reduce((acc, curr) => {
          Object.keys(curr).forEach(k => {
            if (Object.keys(acc).includes(k)) {
              acc[k].push(...curr[k]);
            } else {
              acc[k] = curr[k];
            }
          });
          
          return acc;
        }, {});
        
        // Converting the JSON to array with each key of JSON as separate element in array.
        return Object.keys(json).map(jsonKey => {
          return {
            [jsonKey]: json[jsonKey]
          };
        });
      }
      
      let myArray = [
          { even: [2,4,6], odd: [1,3,5,7], decimals: [3.14, 12.8] },
          { even: [4,6,8], odd: [7,9,11,13], decimals: [111.1] },
          { even: [16,18], odd: [15,15,17] }
      ];
      
      console.log(mergeArray(myArray));

      【讨论】:

      • 感谢您的解释。您的代码适用于我的情况。
      猜你喜欢
      • 1970-01-01
      • 2013-12-15
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      相关资源
      最近更新 更多