0

let str = '<span class="my"> <var suv="inn">';

let regexp = /<(([a-z]+)\s*([^>]*))>/g;

let result = str.matchAll(regexp);
console.log(result[0]);
console.log(result);
//It is an iterable object'
 
console.log("Array from method");
var a = Array.from(result);
console.log(a[0]);
console.log(a[1]);

console.log("for loop method");
for (let value of result){
console.log(value);
}

we can see that when we place the ArrayFrom method first, it logged the values but ForLoop method didn't.

let str = '<span class="my"> <var suv="inn">';

let regexp = /<(([a-z]+)\s*([^>]*))>/g;

let result = str.matchAll(regexp);
console.log(result[0]);
console.log(result);
//It is an iterable object'

console.log("for loop method");
for (let value of result){
console.log(value);
}

console.log("Array from method");
var a = Array.from(result);
console.log(a[0]);
console.log(a[1]);

and similarly when we place the ForLoop method first, it logged the values but ArraFrom method didn't.

Why is not both methods logging after one method logs.
(I really didn't know how else to frame my question, I really hope I'm clear!)

Aashit Garodia
  • 330
  • 1
  • 11
  • _“`/<(([a-z]+)\s*([^>]*))>/g`”_ — HTML is not a regular language. Regular expressions are not the right tool for this job. [Have you tried using an HTML parser instead?](/a/1732454/4642212) Use [DOMParser](//developer.mozilla.org/en-US/docs/Web/API/DOMParser): `new DOMParser().parseFromString(str, "text/html");`. – Sebastian Simon Jun 21 '21 at 16:35
  • If HTML is problem, I tried to replace < by 1 and > by 2 everywhere it becomes `let str = '1span class="my"2 1var suv="inn"2';` `let regexp = /1(([a-z]+)\s*([^2]*))2/g;` the output is still the same, or maybe I didn't understand it? – Aashit Garodia Jun 21 '21 at 16:48
  • That's not going to make html regular. – Charlie Bamford Jun 21 '21 at 16:56
  • Charles and Sebastian are correct but it is immaterial to Aashit's problem as I've discovered. – selfagency Jun 21 '21 at 17:03

1 Answers1

0

What appears to be happening is that after each progression through the iterator, the current item is being removed from the faux array, leaving the iterator empty.

If you stick console.log(Array.from(result).length) before the for...of loop, the length will be 2 and the faux array will be emptied by Array.from() so the for...of loop returns nothing. If you put console.log(Array.from(result).length) twice in a row, the result will be 2 then 0.

If you don't call an Array.from(result).length before, but you stick it just once after for...of the length will also be 0 because it was emptied by the for...of.

This is expected behavior.

selfagency
  • 1,481
  • 1
  • 9
  • 12
  • So all iterators in JavaScript gets emptied after each progression through iterator or is it just `[object RegExp String Iterator]`? – Aashit Garodia Jun 21 '21 at 17:30
  • 2
    "Nothing in the docs on Mozilla says it's supposed to do this." The [article for `.matchAll()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll#return_value) says that the iterable is not restartable. – Corey Jun 21 '21 at 17:39
  • Just got [a very thorough explanation](https://www.reddit.com/r/learnjavascript/comments/o50ids/is_an_iterator_object_supposed_to_automatically/h2k7g8e/?utm_source=reddit&utm_medium=web2x&context=3) on Reddit – selfagency Jun 21 '21 at 18:09
  • @Corey Thanks, I missed that somehow. – selfagency Jun 21 '21 at 18:10