从数组创建对象
Posted
技术标签:
【中文标题】从数组创建对象【英文标题】:Create object from array 【发布时间】:2017-08-15 22:19:16 【问题描述】:我想从数组中的列表创建一个对象。我有一个动态数组,看起来像这样:
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
不要担心内部对象。我只想创建一个这样的结构:
obj =
2007: ...,
2008: ...,
...
请帮忙,谢谢。
【问题讨论】:
【参考方案1】:简单
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"
。函数返回一个对象——这就是为什么函数体被括在括号 => ( ... )
中的原因。扩展运算符在第一次迭代时不执行任何操作,因此将 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
在对象内部传播时,我们的函数返回最终值。
【讨论】:
谢谢!它按要求工作。我从来不知道array.reduce
函数。
如果你喜欢函数式风格,我也喜欢,你应该使用const
。实际上,无论如何您都应该使用它。此外,如果您可以访问 ES Next 休息/扩展语法(例如通过 TypeScript 或 Babel),您可以编写 const obj = yourArray.reduce((o, key) => ( ...o, [key]: whatever), )
甚至避免改变种子:p
@AluanHaddad:好建议,已将帖子转换为CW,欢迎编辑。
关于“功能风格”的方法,在每次迭代中复制对象似乎有点矫枉过正。我建议添加到新对象:yourArray.reduce((o, key) => o[key] = whatever; return o; , )
。其他一切看起来都很棒!
@cameck:谢谢,帖子是 CW,请随时编辑。【参考方案2】:
来自 ECMAScript 2019 的新 Object.fromEntries
使将值从数组转换为对象中的键变得更加容易,如下所示
const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
dynamicArray.map(year => [year,
something: "based",
on: year
])
)
console.log(obj)
【讨论】:
谢谢!你救了我的一天!使用数组 unshift 和 splice 可以做同样的事情吗?【参考方案3】:在带有es6 reduce函数的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
【讨论】:
更短:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), )
@exebook 你能解释一下x
在reduce的return函数中做了什么吗?【参考方案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'
【讨论】:
【参考方案5】:我发现您实际上可以直接将Object.assign()
与展开运算符一起使用。无需使用reduce
或map
函数引入更多复杂性。
只需执行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
【讨论】:
Edited asobject.assign()
需要目标对象作为第一个参数。以前(object.assign(...arr, )
)
是多余的,返回的对象是数组arr
的第一个条目。我不认为它打算改变arr
。
对象分配解决方案即使在接受的答案上也不是主题,因为 op 是从字符串数组而不是对象数组开始
我只是将它用作如何使用它的示例 - 但它也适用于请求的 OP 等字符串数组,正如我所提到的,它将默认密钥为索引所以它将是 0: 'string1', 1: 'string2'
【参考方案6】:
使用 forEach
const arrayKeys=['KEY1','KEY2','KEY3'];
let object=;
arrayKeys.forEach((key)=>
object[key]='property content'
);
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于从数组创建对象的主要内容,如果未能解决你的问题,请参考以下文章