我知道Map中的元素可以按照插入顺序进行迭代。
假设我们有这张地图:
const a = new Map();
a.set('x', 5);
a.set('y', 10);
a.set('z', 5);
我们想在a
中找到第一个元素,值为5
,然后在下一个元素中找到相同值的5
。
// el will be 5, 10, 5...
for(const el of a) {
if(el === 0) {
// How can I iteratate over `a` starting from index(el) + 1
for (??) {}
}
}
如果我使用的是Array
,我们可以做类似的事情(忽略键):
const a = new Array(5, 10, 5);
for(let i = 0; i < a.length; ++i) {
if(a[i] === 5) {
// Here I can start iterating from i + 1
for(let j = i + 1; j < a.length; ++j) {
a[j] === 5 && console.log('FOUND!');
}
}
}
我对iterators
不太熟悉,但是我认为应该可以从地图中的特定元素开始进行迭代。
const x = a.get('x');
// iterate over Map `a` starting from the element that comes after x
我不特别满意的一种解决方案是,每次执行操作const elements = a.entries()
时都获得键或条目的副本,因此我们可以快速对其进行迭代,但是这样做会耗费大量精力额外的内存。
答案 0 :(得分:2)
您可以使用生成器来执行此操作。.
一个优点是您可以将发电机短路。
下面的例子。
const a = new Map();
a.set('x', 5);
a.set('y', 10);
a.set('z', 5);
a.set('a', 10);
a.set('b', 5);
function* findFirstThenNext(m, v) {
let ix = 0;
for (const mm of m) {
if (v === mm[1]) {
yield {ix, key:mm[0]};
}
ix += 1;
}
}
let count = 0;
for (const ret of findFirstThenNext(a, 5)) {
console.log(`Found @${ret.ix} with key ${ret.key}`);
count ++;
if (count >= 2) break;
}
使用for循环和迭代器的混合,您可以创建简单的列表,然后使用迭代器进行两次for循环。
这里的好处是,如果在很多地方使用这种for循环,那么makeOuterInnerIter
函数就可以重复用于任何可迭代的地方。
const a = new Map();
a.set('x', 5);
a.set('y', 10);
a.set('z', 5);
function* makeOuterInnerIter(iter) {
const stack = Array.from(iter);
for (let ol = 0; ol < stack.length; ol += 1) {
yield {
value: stack[ol],
inner: (function *inner() {
for (let il = ol + 1; il < stack.length; il += 1) yield stack[il];
})()
};
}
}
for (const {value: [okey, ovalue], inner} of makeOuterInnerIter(a)) {
console.log(`outer: ${okey}: ${ovalue}`);
for (const [ikey, ivalue] of inner) {
console.log(` inner: ${ikey}: ${ivalue}`);
}
}
答案 1 :(得分:0)
使用生成器的另一种方法:
function* itWrapper(iterator, value) {
let found = false;
for(let item of iterator) {
if(item[1] == value) {
if(found) {
yield 'FOUND!'; // or: yield item[1];
} else {
found = true;
}
}
}
}
然后像这样使用:
for(let item of itWrapper(a[Symbol.iterator](), 5)) {
console.log(item);
}