【问题标题】:Transform an array of objects into a single object将对象数组转换为单个对象
【发布时间】:2019-02-12 21:53:19
【问题描述】:

我正在尝试将一组对象组合成一个对象,该对象合并所有类似属性的值。

objArray = [{
  foo: ["f", "b"],
  bar: ["e"]
}, {
  foo: ["a", "c"],
  bar: ["a", "c"]
}, {
  foo: ["f", "b"],
  bar: ["z"]
}];
const newObj = {
  foo: [],
  bar: []
};
objArray.forEach((obj) => {
  newObj.foo.push(...obj.foo);
  newObj.bar.push(...obj.bar);
});
console.log(newObj);

我用上面的代码得到了想要的输出。使用上面的 forEach 循环是实现我打算做的最好的方法吗?理想情况下,我不想指定要合并的属性,我希望代码自动合并相同的属性名称。

编辑:

我需要支持 IE11

【问题讨论】:

标签: javascript arrays array.prototype.map


【解决方案1】:

可以使用Object#entries() 的嵌套reduce() 来迭代属性,而无需在任何地方硬编码特定的属性名称

objArray = [{
  foo: ["f", "b"],
  bar: ["e"]
}, {
  foo: ["a", "c"],
  bar: ["a", "c"]
}, {
  foo: ["f", "b"],
  bar: ["z"]
}];

const res= objArray.reduce((acc,c)=>{
   return Object.entries(c).reduce((a,[k,v])=>{
       a[k] = (a[k] || []).concat(v)
       return a
   },acc)
},{})

console.log(res)

【讨论】:

【解决方案2】:

您可以将对象的条目用于任意数量的键和值。

var data = [{ foo: ["f", "b"], bar: ["e"] }, { foo: ["a", "c"], bar: ["a", "c"] }, { foo: ["f", "b"], bar: ["z"] }],
    merged = data.reduce((r, o) => 
        Object.entries(o).reduce((s, [k, v]) =>
            Object.assign(s, { [k]: (s[k] || []).concat(v) }), r), {});
        
console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    要达到预期的效果,请使用 Object.keys 和使用 forEach 的两个循环

    1. 使用 forEach 的第一个循环将处理每个对象
    2. 使用 Object.keys 的第二个循环将处理每个对象键并使用键推送到新数组
    3. 使用 Object.hasOwnProperty 以原始数组对象属性在 newObj 中键入值

    objArray = [
      {
        foo: ["f", "b"],
        bar: ["e"],
        zoo: ["z"]
      },
      {
        foo: ["a", "c"],
        bar: ["a", "c"]
      },
      {
        foo: ["f", "b"],
        bar: ["z"]
      }
    ];
    const newObj = {
      foo: [],
      bar: []
    };
    objArray.forEach(obj => {
      Object.keys(obj).forEach(v => {
        if (newObj.hasOwnProperty(v)) {
          newObj[v].push(obj[v]);
        }
      });
    });
    console.log(newObj);

    codepen 供参考 - https://codepen.io/nagasai/pen/MqOpWm?editors=1010

    【讨论】:

    • 如果数组中有一个对象看起来像{ foo: ["f", "b"], bar: ["z"], zoo: ["123"] }
    • @ibrahimmahrir,通过检查 Object.hasOwnProperty 更新了我的答案
    【解决方案4】:

    像你一样使用 forEach,但在里面使用for in

    var objArray = [{foo: ["f", "b"],bar: ["e"]},{foo: ["a", "c"],bar:["a", "c"]},{foo: ["f", "b"],bar: ["z"]}];
    
    var newObj = {};
    
    objArray.forEach(o => {
      for (p in o) {
        if (!(p in newObj)) {
          newObj[p] = [];
        }
        newObj[p] = [...newObj[p], ...o[p]];
      }
    });
    
    console.log(newObj);

    【讨论】:

      【解决方案5】:

      获取@charlietfl 答案并为 IE 编辑它(使用 Object.keys 而不是 Object.entries

      objArray = [{
        foo: ["f", "b"],
        bar: ["e"]
      }, {
        foo: ["a", "c"],
        bar: ["a", "c"]
      }, {
        foo: ["f", "b"],
        bar: ["z"]
      }];
      
      const res = objArray.reduce((acc, c) => {
        return Object.keys(c).reduce((a, k) => {
          let v = c[k];
          a[k] = (a[k] || []).concat(v);
          return a;
        }, acc);
      }, {});
      
      console.log(res)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-10
        • 2013-10-20
        • 2022-01-15
        • 2019-05-08
        • 1970-01-01
        相关资源
        最近更新 更多