Home > Software design >  Array.from() on IterableIterator seemingly mutates parameter
Array.from() on IterableIterator seemingly mutates parameter

Time:12-18

I'm a bit baffled on this one. My code looks like the following:

let matches = code.matchAll(/regex pattern/g);
if (!Array.from(matches).length) {
    matches = code.matchAll(/regex alt pattern/g);
    if (!Array.from(matches).length) return;
}

console.log(Array.from(matches));

My goal here is to check for a pattern, and if nothing is found, check for an alternate. If still nothing is found, I want to return, else, I'm going to do some work with it.

My issue here is that Array.from(matches) for some reason consumes matches. Let's say that the first regex pattern returns a result. The if-statement will be correctly be skipped over, but the console log will print out an empty array. Nothing in matches. Same goes for the alternative regex. If I check for that early return, matches will be empty again. If I comment it out, however, then that console log has a non-empty array.

According to MDN, Array.from() should be making a shallow copy. Why is it instead wiping away that reference?

CodePudding user response:

If you read the MDN doc on what .matchAll() returns, it is a non-restartable iterator. So, you are correct that Array.from() will consume it and you apparently can't use that iterator again.

So, do the Array.from(matches) once and save it to a variable so you aren't trying to use the iterable more than once. Here's one way to do that:

let matches = Array.from(code.matchAll(/regex pattern/g));
if (!matches.length) {
    matches = Array.from(code.matchAll(/regex alt pattern/g));
    if (!matches.length) return;
}

console.log(matches);
  • Related