cal*_*lum 100 javascript ecmascript-6
出于某种原因,我无法在MDN文档中找到这个简单的东西(也许我只是错过了它).
我希望这可行:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
Run Code Online (Sandbox Code Playgroud)
......但是第一行抛出 TypeError: (var)[Symbol.iterator] is not a function
如何从普通对象制作地图?我是否真的必须先将其转换为键值对数组?
nil*_*ils 150
是的,Map构造函数采用一组键值对.
Object.entries是ES2017(19.1.2.5)中提供的一种新的Object静态方法.
const map = new Map(Object.entries({foo: 'bar'}));
map.get('foo'); // 'bar'
Run Code Online (Sandbox Code Playgroud)
它目前已在Firefox 46+和Edge 14+以及更新版本的Chrome中实施
如果您需要支持较旧的环境并且不能选择转换,请使用polyfill,例如georg推荐的polyfill:
Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 73
请使用生成器函数查看nils的答案Object.entries和/或bergi的答案.虽然Object.entries在问题被问到时尚未出现在规范中,但它是在第4阶段,因此在2016年4月(仅仅)回到polyfill并使用是安全的.(更多关于这里的阶段.)和发电机功能在ES2015.OP特别要求避免中间人,虽然发电机并没有完全避免这种情况,但它比下面或(稍微)做得更好Object.enties.
FWIW,使用Object.entries:
[name, value]要传递给的数组数组new MapMap构造函数调用阵列上的函数来获得一个迭代器; 数组创建并返回数组处理器对象.Map构造函数使用了迭代器对象获取的条目(该[name, value]阵列),并建立映射使用发电机:
Map构造函数调用生成器对象的函数从它那里得到一个迭代器; 生成器对象返回自身Map构造函数使用生成器对象(作为一个迭代)来获得条目(在[name, value]阵列)和构建地图所以:少一个中介(数组来自Object.entries).
但是,使用Object.entries更简单,并且99.999%的时间创建该数组不是问题.真的,任何一个.但他们都比下面更好.:-)
原始答案:
要初始化a Map,可以使用任何将键/值对作为数组返回的迭代器,例如数组数组:
const map = new Map([
['foo', 'bar']
]);
Run Code Online (Sandbox Code Playgroud)
没有从对象到地图的内置转换,但它很容易完成Object.keys:
const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
Run Code Online (Sandbox Code Playgroud)
当然,您可以给自己一个工作函数来处理:
function buildMap(obj) {
let map = new Map();
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
return map;
}
Run Code Online (Sandbox Code Playgroud)
然后
const map = buildMap({foo: 'bar'});
Run Code Online (Sandbox Code Playgroud)
或者这里看起来更像l33t(还是那件事?)版本:
function buildMap(obj) {
return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}
Run Code Online (Sandbox Code Playgroud)
(是的,Map#set返回地图参考.有些人认为,这是一abusage的reduce.)
或者我们真的可以在默默无闻中超越:
const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());
Run Code Online (Sandbox Code Playgroud)
不,我永远不会那样做真的.:-)
Ber*_*rgi 30
我是否真的必须先将其转换为键值对数组?
不,键值对数组的迭代器就足够了.您可以使用以下内容来避免创建中间数组:
function* entries(obj) {
for (let key in obj)
yield [key, obj[key]];
}
const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'
Run Code Online (Sandbox Code Playgroud)
Nils的答案描述了如何将对象转换为地图,我发现这非常有用.但是,OP也想知道这些信息在MDN文档中的位置.虽然在最初询问问题时它可能不存在,但它现在位于将对象转换为地图标题下的Object.entries()的MDN页面上,其中指出:
将对象转换为地图
该
new Map()构造函数接受的迭代entries.有了Object.entries,您可以轻松转换Object为Map:Run Code Online (Sandbox Code Playgroud)const obj = { foo: 'bar', baz: 42 }; const map = new Map(Object.entries(obj)); console.log(map); // Map { foo: "bar", baz: 42 }
ES6
将对象转换为地图:
const objToMap = (o) => new Map(Object.entries(o));
Run Code Online (Sandbox Code Playgroud)
将地图转换为对象:
const mapToObj = (m) => [...m].reduce( (o,v)=>{ o[v[0]] = v[1]; return o; },{} )
Run Code Online (Sandbox Code Playgroud)
注意:mapToObj 函数假定映射键是字符串(否则会失败)
const myMap = new Map(
Object
.keys(myObj)
.map(
key => [key, myObj[key]]
)
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63219 次 |
| 最近记录: |