【问题标题】:Create object from forEach从 forEach 创建对象
【发布时间】:2016-12-09 17:53:49
【问题描述】:

我试图弄清楚是否有办法将此代码重写为单个对象创建:

my_array = [
  {key: 1, value: "foo"},
  {key: 2, value: "bar"}
];

let my_obj = {};
my_array.forEach((elem) => {
  my_obj[elem.key] = elem.value;
});

我想做的是这样的:

my_array = [
  {key: 1, value: "foo"},
  {key: 2, value: "bar"},
];

const my_obj = ...?

有没有一种方法可以进行相当于forEach 调用的一次性转换?

【问题讨论】:

  • 你可以使用Map 代替(我脑子里有一个可以工作的单行)。
  • 你在描述reduce
  • 使用reduce lke this my_obj = my_array.reduce( (a, b)=>{ a[b.key] = b.value; return a;}, {})
  • IMO,在这种特殊情况下,常规 for 循环或 forEach 将是您仅使用内置函数可以做的最清晰的事情。如果您真的想一次性完成,我会将循环放在一个命名良好的函数中。
  • “我想要的是能够在那里使用 const” - 请注意,即使使用显示的代码,您也可以使用 const 而不是 let。使用const 不会阻止您更改对象的内容,它只会阻止您将变量重新分配给其他对象。

标签: javascript functional-programming javascript-objects


【解决方案1】:

在 ES6 中,你可以使用Object.assign:

const obj = Object.assign({}, ...my_array.map(x => ({ [x.key]: x.value })));

// Or:
const obj = Object.assign({}, ...my_array.map(({ key, value }) => ({ [key]: value })));

这会将每个{ key: foo, value: bar } 转换为{ foo: bar },然后使用 Object.assign 将它们合并为一个对象。 (spread operator 用作 Object.assign 需要一个变量的参数列表。)

【讨论】:

  • 第二种形式的 [key] 做了什么?
  • @adaba 当属性名称是变量时,这是一种在{ } 中定义属性的方法。例如,如果你这样做:const myVariable = "a" + "b" + "c"; const myObject = { [myVariable]: 123 };,那么myObject.abc === 123
【解决方案2】:

您可以使用reduce 函数。它应该像这样工作:

my_array = [
  {key: 1, value: "foo"},
  {key: 2, value: "bar"}
];

let my_obj = my_array.reduce(function(obj, elem) {
    obj[elem.key] = elem.value;
    return obj;
}, {});

// my_obj = { "1": "foo", "2": "bar" }

【讨论】:

    【解决方案3】:

    您可以使用Array.prototype.reduce() 实现此目的:

    var my_array = [{key: 1, value:"foo"}, {key: 2, value:"bar"}];
      
    var my_object = my_array.reduce(function(prev, curr) {
      prev[curr.key] = curr.value;
      return prev;
    }, {});
    
    console.log(my_object); // {"1": "foo", "2": "bar"}

    或者,使用 ES6 语法:

    const my_object = my_array.reduce((prev, curr) => {
        prev[curr.key] = curr.value;
        return prev;
    }, {});
    

    【讨论】:

    • 如果你想要它超级瘦,你可以选择(prev, curr) => (prev[curr.key] = curr.value, prev)
    • @JDB:在这种情况下,如果支持对象扩展运算符,我可能更喜欢(prev, curr) => Object.assign(prev, {[curr.key]: curr.value})(prev, curr) => {...prev, [curr.key]: curr.value}。在我看来更具可读性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 2014-01-14
    • 2013-10-12
    相关资源
    最近更新 更多