Answers:
是的,Map
构造函数采用键值对数组。
Object.entries
是ES2017(19.1.2.5)中可用的新的Object静态方法。
const map = new Map(Object.entries({foo: 'bar'}));
map.get('foo'); // 'bar'
目前已在Firefox 46+和Edge 14+及更高版本的Chrome中实现
如果您需要支持较旧的环境,而不能选择进行移植,请使用polyfill,例如georg建议的填充:
Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
在节点7.x的正确(无标志)登陆顺便说一句
请使用生成器函数查看nils的答案Object.entries
和/或bergi的答案。尽管Object.entries
在提出问题时尚不在规范中,但它是在第4阶段进行的,因此可以安全地进行填充和甚至在2016年4月使用(也就是)。(有关此阶段的更多信息。)生成器功能在ES2015中。OP明确要求避免中介,虽然生成器并没有完全避免中介,但它比下面的(或略)做得更好Object.enties
。
FWIW,使用Object.entries
:
[name, value]
要传递给的数组数组new Map
Map
构造函数调用数组以得到一个迭代器上的功能; 数组创建并返回一个数组插入对象。Map
构造函数使用了迭代器对象获取的条目(该[name, value]
阵列),并建立映射使用生成器:
Map
构造函数调用生成器对象的函数从它那里得到一个迭代器; 生成器对象返回自身Map
构造函数使用生成器对象(作为一个迭代)来获得条目(在[name, value]
阵列)和构建地图因此:减少了一个中介(来自的数组Object.entries
)。
但是,使用起来Object.entries
更简单,并且在99.999%的时间内创建该阵列都不是问题。真的,无论是哪一个。但是它们都比下面的要好。:-)
原始答案:
要初始化Map
,您可以使用任何将键/值对作为数组返回的迭代器,例如数组数组:
const map = new Map([
['foo', 'bar']
]);
没有从对象到地图的内置转换,但是很容易做到Object.keys
:
const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
当然,您可以给自己一个辅助函数来处理该问题:
function buildMap(obj) {
let map = new Map();
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
return map;
}
然后
const map = buildMap({foo: 'bar'});
或者这是一个看起来更轻巧的版本(那还是一回事吗?):
function buildMap(obj) {
return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}
(是的,Map#set
返回地图参考。有些人认为,这是一abusage的reduce
。)
或者,我们真的可以超越晦涩之处:
const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());
不,我永远不会真正做到这一点。:-)
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
。
new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133
我真的必须首先将其转换为键值对数组的数组吗?
不,键值对数组的迭代器就足够了。您可以使用以下命令来避免创建中间数组:
function* entries(obj) {
for (let key in obj)
yield [key, obj[key]];
}
const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'
if(!obj.hasOwnProperties(key)) continue;
在for循环条件之后立即执行操作,以确保不产生从对象原型继承的属性(除非您信任该对象,但是在使用进行对象迭代时应始终这样做)in
作为一个好习惯)。
.hasOwnProperty
属性,而必须使用Object.prototype.hasOwnProperty.call(obj, key)
function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
。这也yield [key, obj[key]] as const;
将有助于TypeScript认识到它产生的是元组,而不是数组。
Nils的答案描述了如何将对象转换为地图,我发现这非常有用。但是,OP还想知道此信息在MDN文档中的何处。最初问问题时可能还没有出现,但现在位于“ 将对象转换为地图 ”标题下的Object.entries()的MDN页面上,该状态指出:
将对象转换为地图
该
new Map()
构造函数接受一个可迭代的entries
。使用Object.entries
,您可以轻松地从转换Object
为Map
:const obj = { foo: 'bar', baz: 42 }; const map = new Map(Object.entries(obj)); console.log(map); // Map { foo: "bar", baz: 42 }
const myMap = new Map(
Object
.keys(myObj)
.map(
key => [key, myObj[key]]
)
)
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
。
另外,您可以使用lodash toPairs方法:
const _ = require('lodash');
const map = new Map(_.toPairs({foo: 'bar'}));
ES6
将对象转换为地图:
const objToMap = (o) => new Map(Object.entries(o));
将地图转换为对象:
const mapToObj = (m) => [...m].reduce( (o,v)=>{ o[v[0]] = v[1]; return o; },{} )
注意:mapToObj函数假定地图键是字符串(否则将失败)
借助一些JQuery,
const myMap = new Map();
$.each( obj, function( key, value ) {
myMap[key] = value;
});
Object.entries
的确是更好的方法Object.keys
,而bergi的生成器函数方法比Object.keys
或都更直接Object.entries
。