es6 map/set iterate from certain item (backwards)

2019-08-12 08:35发布

问题:

Beginner here, I'm a bit lost with es6 set, map and generators.

How can I select an item in a map, then iterate backwards from that point on effectively? Preferably without going through the whole set/map.

let v = myMap.get('key')

so, from 'v' to the beginning of the map (backwards)?

thank you!

回答1:

You can create a set of iteration helpers and then compound to create the effect you want:

/* 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];
}

You can then use and compound like this:

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)));


回答2:

What you probably want is a slice of the keys from the first element to the index of the key, reverse that, iterate over that and get the values from the map.

I am assuming your map is an object:

let keys = Object.keys(map);
return keys.slice(0, keys.indexOf('key')).map((k) => map[k]);

You don't really need a generator.