【发布时间】:2015-09-10 09:27:56
【问题描述】:
这里是初学者, 我对 es6 set、map 和生成器有点迷茫。
如何在地图中选择一个项目,然后从该点有效地向后迭代?最好不要通过整个集合/地图。
let v = myMap.get('key')
那么,从“v”到地图的开头(向后)?
谢谢!
【问题讨论】:
标签: dictionary set ecmascript-6
这里是初学者, 我对 es6 set、map 和生成器有点迷茫。
如何在地图中选择一个项目,然后从该点有效地向后迭代?最好不要通过整个集合/地图。
let v = myMap.get('key')
那么,从“v”到地图的开头(向后)?
谢谢!
【问题讨论】:
标签: dictionary set ecmascript-6
您可以创建一组迭代助手,然后复合以创建您想要的效果:
/* iterTo iterates the iterable from the start and up to (inclusive) key is found.
The function "understands" the Map type when comparing keys as well as
any other iterables where the value itself is the key to match. */
function* iterTo(iterable, key) {
for(let i of iterable) {
yield i;
if((iterable instanceof Map && i[0] === key) || i === key)
return;
}
}
// Same as iterTo, but starts at the key and goes all the way to the end
function* iterFrom(iterable, key) {
let found = false;
for(let i of iterable) {
if(found = (found || (iterable instanceof Map && i[0] === key) || i === key))
yield i;
}
}
// reverseIter creates a reverse facade for iterable
function* reverseIter(iterable) {
let all = [...iterable];
for(let i = all.length; i--; )
yield all[i];
}
然后您可以像这样使用和复合:
let m = new Map();
m.set(1, 'a');
m.set(2, 'b');
m.set(3, 'c');
m.set(4, 'd');
m.set(5, 'e');
let s = new Set();
s.add(100);
s.add(200);
s.add(300);
s.add(400);
console.log(...iterTo(m, 3), ...iterFrom(m, 3));
console.log(...reverseIter(iterTo(m, 3)), ...reverseIter(iterFrom(m, 3)));
console.log(...reverseIter(iterTo(s, 200)));
【讨论】:
Maps 和 Sets 只是不提供用于向后或部分迭代的 API。如果您真的必须这样做,我想转换为数组并使用slice 会更有效。
|= 运算符看起来像一个错误。比在布尔值上使用按位整数运算符更好地写出来。
slice,我看不出它是如何提高效率的,该函数仍应为yield 值,那么首先切片的意义何在?
您可能想要的是从第一个元素到key 的索引的keys 中的slice,反转它,迭代它并从映射中获取值。
我假设你的 map 是一个对象:
let keys = Object.keys(map);
return keys.slice(0, keys.indexOf('key')).map((k) => map[k]);
你真的不需要生成器。
【讨论】:
Object.keys() 根本不会得到 Map 密钥。如果有任何Map.prototype.keys() 会,但我看不出这如何有助于防止迭代整个 Map 条目。