从数组创建对象


83

我想从数组列表中创建对象。我有一个动态数组,看起来像这样:

var dynamicArray = ["2007", "2008", "2009", "2010"];

并使用一些javascript es6,我想制作一个像这样的对象:

const obj = {
    2007: {
        x: width / 5,
        y: height / 2
    },
    2008: {
        x: (2 / 5) * width,
        y: height / 2
    },
    2009: {
        x: (3 / 5) * width,
        y: height / 2
    },
    2010: {
        x: (4 / 5) * width,
        y: height / 2
    }
}

不用担心内部对象,而只想要一个这样的make结构:

 obj = {
      2007: ...,
      2008: ...,
      ...
    }

请帮忙,谢谢。


2
好的。你尝试了什么?你困在哪里?你做了什么研究?例如,您看过这个吗?
TJ Crowder

Answers:


202

只是

 const obj = {};

 for (const key of yourArray) {
      obj[key] = whatever;
 }

或者,如果您更喜欢“实用”风格:

 const obj = yourArray.reduce((o, key) => Object.assign(o, {[key]: whatever}), {});

使用现代对象传播运算符:

const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})

例:

[
  { id: 10, color: "red" },
  { id: 20, color: "blue" },
  { id: 30, color: "green" }
].reduce((acc, cur) => ({ ...acc, [cur.color]: cur.id }), {})

输出:

{red: 10, blue: 20, green: 30}

下面是它的工作原理:

reduce使用空对象({}末尾为空)初始化,因此第一次迭代变量为acc = {} cur = { id: 10, color: "red" }。函数返回一个对象-这就是为什么函数主体包含在括号中=> ({ ... })。Spread运算符在第一次迭代时不执行任何操作,因此red: 10被设置为第一项。

在第二次迭代中,变量为acc = { red: 10 } cur = { id: 20, color: "blue" }。在这里,散布运算符展开 acc,函数返回{ red: 10, blue: 20 }

第三次迭代acc = { red: 10, blue: 20 } cur = { id: 30, color: "green" },因此当acc在对象内部传播时,我们的函数将返回最终值。


1
谢谢!它按要求工作。我从不知道array.reduce功能。
侯赛因·德加姆瓦拉

如果您喜欢实用的样式(我愿意),则应使用const。实际上,无论如何,您都应该使用它。此外,如果您有权使用ES Next的rest / const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})
read

1
@AluanHaddad:很好的建议,将帖子转换为CW,随时进行编辑。
乔治

({... o,[key]:候选人Doc [key]})..其中候选人Doc是一些pojo。我只想使用候选人文档中定义的值。但是我对括号感到困惑,似乎无法获得“ return”或if语句。您能指出我正确的方向吗?不要害怕阅读文档。
terary

1
@cameck:谢谢,帖子是CW,随时可以编辑。
乔治

33

Object.fromEntriesECMAScript 2019中的新功能使将数组中的值转换为对象中的键变得更加容易,如下所示

const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map(year => [year, {
    something: "based",
    on: year
  }])
)

console.log(obj)


17

在带有es6的js数组减少函数中,我这样做

let x = [1,2,3]
let y = x.reduce((acc, elem) => {
  acc[elem] = elem // or what ever object you want inside
  return acc
}, {})
console.log(y) // {1:1, 2:2, 3:3}

3
甚至更短:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
exebook

4
var keys = ['key1', 'key2', 'key3']

var object = Object.assign({}, ...Object.entries({...keys}).map(([a,b]) => ({ [b]: 'someValue' })))
console.log(object)

这将产生

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }

0

我发现您实际上可以Object.assign()直接与传播操作符一起使用。无需使用reducemap函数引入更多的复杂性。

简单地做Object.assign(...yourArray, {}),您将得到您想要的结果。如果您想将对象数组合并到另一个对象中,则可以调用Object.assign(...yourArray, yourObject),它也可以正常工作。

您也可以使用相同的方法将两个数组合并为一个对象,即使其中一个数组不包含对象,而仅包含原始值-但是,如果这样做,则需要确保至少一个数组仅包含对象,例如原语将默认为其索引作为key,因此,如果有重复的键,则会出错。

但是,出于OP的目的,他与空对象合并时不会出现此类错误,这是最安全的方法。

const arr = [
  { a: 0 },
  { c: 1 },
  { e: 2 },
];

const obj = Object.assign(...arr, {});

console.log(obj)

// Results to:
// Object { a: 0, c: 1, e: 2 }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.