如何从键值对数组中创建对象?

kjo*_*kjo 47 javascript

在Python中,可以向dict1构造函数传递一系列键值对:

>>> dict([['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']])
{'age': 42, 'name': 'Bob', 'breakfast': 'eggs'}
Run Code Online (Sandbox Code Playgroud)

除了为此目的定义我自己的函数之外,我想不出用JavaScript做任何事情的方法:

function pairs_to_object(pairs) {
    var ret = {};
    pairs.forEach(function (p) { ret[p[0]] = p[1]; });
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

但我是一个JS noob ......对于这种对 - 对象转换,有没有内置的东西?

1出于这个问题的目的,我将Python dicts视为Python对象的JS对象,当然,相似性仅限于它们都是键值集合的事实.

tri*_*cot 57

Object.fromEntries做的工作.在撰写本文时,它是第3阶段的ES提案,可在FireFox 63中使用.

在该功能变得广泛可用之前,您可以使用以下ES6代码自行定义:

Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
Run Code Online (Sandbox Code Playgroud)

一个Object.entries好处是这个方法与(ES2017)相反,所以现在你可以在对象和数组表示之间来回:

const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const obj = Object.fromEntries(arr);
console.log(obj);
// ... and back:
const arr2 = Object.entries(obj);
console.log(arr2); // copy of the original array (omitting duplicate keys)
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

ES6地图

对于键/值对,可以使用普通对象的替代方法:Map.

它的构造函数接受数组对的格式:

// Demo:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];

const mp = new Map(arr);

// Get one particular value:
console.log(mp.get('age'));
// Get all the keys:
console.log(...mp.keys());
// Get all the values:
console.log(...mp.values());
// Get all the key/value pairs:
console.log(...mp.entries());
Run Code Online (Sandbox Code Playgroud)

如果你真的需要一个普通的对象,那么这没用,但Map可能会提供一个可行的选择.

  • 在2018年ES草案中,可以使用[对象扩展语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)而不是`Object.assign` ,如下所示:`<array> .reduce((o,[k,v])=>({... o,[k]:v}),{})`. (2认同)

Chr*_*don 44

您可以使用reduce功能

x = [[1,2],[3,4],[5,6]];
o = x.reduce(function(prev,curr){prev[curr[0]]=curr[1];return prev;},{})
Run Code Online (Sandbox Code Playgroud)

o现在相当于 {1:2, 3:4, 5:6}

如果输入数组稀疏,则需要if(curr!=undefined)在赋值时添加测试,但请确保仍返回"prev".

如果你的元组比简单的[key,value]更复杂,你可以简单地改变"prev"的分配方式.例如:prev["key-"+curr[0].toString()]=curr[1]*2;


Koe*_*ers 14

JavaScript对象/字典/关联数组本身没有这样的构造函数.

正如您自己所说,您当然可以使用函数方法构建自己的函数,使用reduce函数,如其他答案中所述.当然,经典或更新的forEach循环也可以使用.但是没有任何内置的东西.


Eri*_*ric 11

Lodash的fromPairs函数将执行此操作:

const _ = require('lodash')
const kvPairs = [['a', 1], ['b', 2]]
_.fromPairs(kvPairs)
// => { a: 1, b: 2 }
Run Code Online (Sandbox Code Playgroud)


Wil*_*een 7

Object.fromEntries()

Object对象上有一个名为的方法Object.fromEntries(iterable)。来自可迭代对象的迭代器对象必须生成一个包含 2 个元素的数组。第一个(索引 0)数组元素将是对象键,第二个是值。

MDN 非常准确地描述了这一点:

Object.fromEntries()方法采用键值对列表并返回一个新对象,其属性由这些条目给出。iterable 参数应该是一个实现 @@iterator方法的对象,该对象返回一个迭代器对象,该对象生成一个双元素数组类对象,其第一个元素是将用作属性键的值,其第二个元素是与该属性键关联的值。


如何使用:

您甚至不需要知道可迭代对象的细节即可使用该Object.fromEntries()方法。您始终可以在以下对象上使用该方法:

  • 2 维数组,其中内部/嵌套数组有 2 个元素
  • 地图

下面是一个例子:

// map example:
const map = new Map([ ['hi', 'there'], ['foo', 2] ]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // { hi: "there", foo: 2 }

// array example:
const array = [ ['0', '00'], ['1', '11'], ['2', '22'] ];
const objFromArray = Object.fromEntries(array);
console.log(objFromArray); // { 0: "00", 1: "11", 2: "22" }
Run Code Online (Sandbox Code Playgroud)

注意,浏览器兼容性!

在撰写本文时(2019 年 12 月),此方法相对较新,并非所有浏览器都已实现。为了使用此方法并确保您的 JS 代码将在所有浏览器中运行,您可能必须将您的代码转换为早期版本的 JS。