5

Is there a nice way (except using JS exceptions) to stop forEach loop in ES6 Map object (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach )

From example provided on MDN - is there a way to stop enumeration on 'bar' (skip bar):

function logMapElements(value, key, map) {
    console.log(`m[${key}] = ${value}`);
}
new Map([['foo', 3], ['bar', {}], ['baz', undefined]]).forEach(logMapElements);

For the people who suggest to close this question: yes, it is similar to the questions about Array.prototype.forEach.
But at the same time is different: most of the suggested answers won't work with ES6 set and map. Only throwing the exception will work, but I ask for some other ways

vmg
  • 9,920
  • 13
  • 61
  • 90
  • It is similar, but at the same time is different. Most of suggested answers won't work with ES6 set and map. Only throwing the exception will work, but I ask for some other ways. – vmg Mar 10 '17 at 22:56

2 Answers2

10

There is no good reason to use forEach any more in ES6. You should use iterators and for … of loops from which you can ordinarily break:

const m = new Map([['foo', 3], ['bar', {}], ['baz', undefined]]);
for (let [key, value] of m) {
    console.log(`m[${key}] = ${value}`);
}
John Jiang
  • 11,069
  • 12
  • 51
  • 60
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • IE11 does not support iterators – vmg Mar 11 '17 at 20:03
  • @vmg Either switch to Edge or use a transpiler then :-) – Bergi Mar 11 '17 at 23:00
  • 1
    @JDB `forEach` does *not* support chaining, it returns `undefined`. It is only suitable for side effects in the callback, and for side effects `for … of` is the better solution. For functional programming, you'll be looking for `map`, `filter` and the others that build on `reduce`. – Bergi Mar 13 '17 at 16:03
  • @vmg It also doesn't support forEach, or does it? – Mathijs Segers Apr 12 '18 at 12:13
0

For those who don't want for-of, the following approach can be applied:

const length = myMap.size;
const iterator = myMap.entries();
for (let i = 0; i < length; i++) {
  const item = iterator.next().value;
  console.log(`myMap[${itemkey}] = ${value}`);
}

A benefit that I have personally encountered is that this approach produces less code during es5 transpilation (using Typescript transpiler with all its __values and __read definitions)...

dhilt
  • 18,707
  • 8
  • 70
  • 85