如何将普通对象转换为ES6映射?

时间:2021-10-30 19:37:14

For some reason I can't find this simple thing in the MDN docs (maybe I'm just missing it).

由于某些原因,我在MDN文档中找不到这个简单的东西(也许我只是错过了它)。

I expected this to work:

我希望这能奏效:

const map = new Map({foo: 'bar'});

map.get('foo'); // 'bar'

...but the first line throws TypeError: (var)[Symbol.iterator] is not a function

…但是第一行抛出TypeError: (var)[符号。不是函数

How do I make a Map from a plain object? Do I really have to first convert it into an array of arrays of key-value pairs?

如何用一个普通的物*作地图?我真的必须首先把它转换成键-值对的数组吗?

6 个解决方案

#1


67  

To initialize a Map, you can use any iterator that returns key/value pairs as arrays, such as an array of arrays:

要初始化映射,可以使用任何返回键/值对的迭代器作为数组,例如数组的数组:

const map = new Map([
    ['foo', 'bar']
]);

There's no built-in conversion from object to map, but it's easily done with Object.keys:

没有从对象到映射的内置转换,但是使用objecter很容易。

const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
    map.set(key, obj[key]);
});

You can, of course, give yourself a worker function to handle that:

当然,你可以给自己一个worker函数来处理它:

function buildMap(obj) {
    let map = new Map();
    Object.keys(obj).forEach(key => {
        map.set(key, obj[key]);
    });
    return map;
}

Then

然后

const map = buildMap({foo: 'bar'});

Or here's a more l33t-looking (is that still a thing?) version:

或者这里有一个更像l33的版本(这仍然是一个东西吗?)

function buildMap(obj) {
    return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}

(Yes, Map#set returns the map reference. Some would argue this is an abusage of reduce.)

(是的,Map#set返回Map引用。有人会说,这是滥用减排。

Or we can really go over-the-top on obscurity:

或者我们真的可以在默默无闻中做得过火:

const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());

No, I would never do that for real. :-)

不,我绝不会那样做。:-)

#2


69  

Yes, the Map constructor takes an array of key-value pairs.

是的,Map构造函数接受键-值对数组。

Object.entries is a new Object static method available in ES2017 (19.1.2.5).

对象。条目是ES2017中一个新的对象静态方法(19.1.2.5)。

const map = new Map(Object.entries({foo: 'bar'}));

map.get('foo'); // 'bar'

It's currently implemented in Firefox 46+ and Edge 14+ and newer versions of Chrome

它目前在Firefox 46+和Edge 14+以及更新版本的Chrome中实现

If you need to support older environments and transpilation is not an option for you, use a polyfill, such as the one recommended by georg:

如果您需要支持较旧的环境,并不是一个选择,使用一个polyfill,例如georg推荐的:

Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);

#3


24  

Do I really have to first convert it into an array of arrays of key-value pairs?

我真的必须首先把它转换成键-值对的数组吗?

No, an iterator of key-value pair arrays is enough. You can use the following to avoid creating the intermediate array:

不,键-值对数组的迭代器就足够了。您可以使用以下方法来避免创建中间数组:

function* entries(obj) {
    for (let key in obj)
        yield [key, obj[key]];
}

const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'

#4


5  

The answer by Nils describes how to convert objects to maps, which I found very useful. However, the OP was also wondering where this information is in the MDN docs. While it may not have been there when the question was originally asked, it is now on the MDN page for Object.entries() under the heading Converting an Object to a Map which states:

Nils给出的答案描述了如何将对象转换成映射,我发现这非常有用。然而,OP也想知道这些信息在MDN文档的哪里。当问题最初被提出时,它可能不在那里,但现在它出现在Object.entries()的MDN页面上,标题下的对象转换为映射,其中写道:

Converting an Object to a Map

将对象转换为映射

The new Map() constructor accepts an iterable of entries. With Object.entries, you can easily convert from Object to Map:

新的Map()构造函数接受可迭代的条目。与对象。条目,您可以很容易地从对象转换为映射:

const obj = { foo: 'bar', baz: 42 }; 
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

#5


4  

const myMap = new Map(
    Object
        .keys(myObj)
        .map(
            key => [key, myObj[key]]
        )
)

#6


3  

Alternatively you can use the lodash toPairs method:

您也可以使用lodash toPairs方法:

const _ = require('lodash');
const map = new Map(_.toPairs({foo: 'bar'}));

#1


67  

To initialize a Map, you can use any iterator that returns key/value pairs as arrays, such as an array of arrays:

要初始化映射,可以使用任何返回键/值对的迭代器作为数组,例如数组的数组:

const map = new Map([
    ['foo', 'bar']
]);

There's no built-in conversion from object to map, but it's easily done with Object.keys:

没有从对象到映射的内置转换,但是使用objecter很容易。

const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
    map.set(key, obj[key]);
});

You can, of course, give yourself a worker function to handle that:

当然,你可以给自己一个worker函数来处理它:

function buildMap(obj) {
    let map = new Map();
    Object.keys(obj).forEach(key => {
        map.set(key, obj[key]);
    });
    return map;
}

Then

然后

const map = buildMap({foo: 'bar'});

Or here's a more l33t-looking (is that still a thing?) version:

或者这里有一个更像l33的版本(这仍然是一个东西吗?)

function buildMap(obj) {
    return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}

(Yes, Map#set returns the map reference. Some would argue this is an abusage of reduce.)

(是的,Map#set返回Map引用。有人会说,这是滥用减排。

Or we can really go over-the-top on obscurity:

或者我们真的可以在默默无闻中做得过火:

const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());

No, I would never do that for real. :-)

不,我绝不会那样做。:-)

#2


69  

Yes, the Map constructor takes an array of key-value pairs.

是的,Map构造函数接受键-值对数组。

Object.entries is a new Object static method available in ES2017 (19.1.2.5).

对象。条目是ES2017中一个新的对象静态方法(19.1.2.5)。

const map = new Map(Object.entries({foo: 'bar'}));

map.get('foo'); // 'bar'

It's currently implemented in Firefox 46+ and Edge 14+ and newer versions of Chrome

它目前在Firefox 46+和Edge 14+以及更新版本的Chrome中实现

If you need to support older environments and transpilation is not an option for you, use a polyfill, such as the one recommended by georg:

如果您需要支持较旧的环境,并不是一个选择,使用一个polyfill,例如georg推荐的:

Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);

#3


24  

Do I really have to first convert it into an array of arrays of key-value pairs?

我真的必须首先把它转换成键-值对的数组吗?

No, an iterator of key-value pair arrays is enough. You can use the following to avoid creating the intermediate array:

不,键-值对数组的迭代器就足够了。您可以使用以下方法来避免创建中间数组:

function* entries(obj) {
    for (let key in obj)
        yield [key, obj[key]];
}

const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'

#4


5  

The answer by Nils describes how to convert objects to maps, which I found very useful. However, the OP was also wondering where this information is in the MDN docs. While it may not have been there when the question was originally asked, it is now on the MDN page for Object.entries() under the heading Converting an Object to a Map which states:

Nils给出的答案描述了如何将对象转换成映射,我发现这非常有用。然而,OP也想知道这些信息在MDN文档的哪里。当问题最初被提出时,它可能不在那里,但现在它出现在Object.entries()的MDN页面上,标题下的对象转换为映射,其中写道:

Converting an Object to a Map

将对象转换为映射

The new Map() constructor accepts an iterable of entries. With Object.entries, you can easily convert from Object to Map:

新的Map()构造函数接受可迭代的条目。与对象。条目,您可以很容易地从对象转换为映射:

const obj = { foo: 'bar', baz: 42 }; 
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

#5


4  

const myMap = new Map(
    Object
        .keys(myObj)
        .map(
            key => [key, myObj[key]]
        )
)

#6


3  

Alternatively you can use the lodash toPairs method:

您也可以使用lodash toPairs方法:

const _ = require('lodash');
const map = new Map(_.toPairs({foo: 'bar'}));