如何在 JavaScript 中重做 for...of 循环?
How do I redo a for...of loop in JavaScript?
在Ruby中,redo
关键字可用于返回到循环的开头而不消耗输入。我想对 JavaScript.
中的 for...of
循环做同样的事情
const scan = lexer => function* (string) {
let [token, table] = lexer;
for (const character of string) {
const next = table.get(character);
if (next) {
[token, table] = next.value;
} else if (token) {
yield token.value;
[token, table] = lexer;
// redo the current iteration without consuming input
} else {
throw new SyntaxError("Unexpected character", character);
}
}
if (token) yield token.value;
else throw new SyntaxError("Unexpected end of input");
}
通常情况下,您只需不增加常规 for
循环的索引即可。但是,我必须使用 for...of
循环,因为它会遍历字符串的 Unicode 代码点,而常规 for
循环会遍历字符串的 UTF-16 代码单元。
如何在不重复代码的情况下返回到循环的开头?
只需使用一个内循环:
for (const character of string) {
while(true) {
const next = table.get(character);
if (next) {
[token, table] = next.value;
break;
} else if (token) {
yield token.value;
[token, table] = lexer;
// don't break, redo
} else {
throw new SyntaxError("Unexpected character", character);
break;
}
}
}
重启整个循环:
在你的例子中其实很简单:
yield* scan(lexer)(string);
return;
如果您不想重新启动整个功能,请添加一个 IIFE 并记住:
yield* (function redo*() {
//...
yield* redo();
return;
})();
如果你真的需要跳转,使用标签(请不要):
restart: while(true) {
// do stuff
continue restart;
//...
break;
}
在Ruby中,redo
关键字可用于返回到循环的开头而不消耗输入。我想对 JavaScript.
for...of
循环做同样的事情
const scan = lexer => function* (string) {
let [token, table] = lexer;
for (const character of string) {
const next = table.get(character);
if (next) {
[token, table] = next.value;
} else if (token) {
yield token.value;
[token, table] = lexer;
// redo the current iteration without consuming input
} else {
throw new SyntaxError("Unexpected character", character);
}
}
if (token) yield token.value;
else throw new SyntaxError("Unexpected end of input");
}
通常情况下,您只需不增加常规 for
循环的索引即可。但是,我必须使用 for...of
循环,因为它会遍历字符串的 Unicode 代码点,而常规 for
循环会遍历字符串的 UTF-16 代码单元。
如何在不重复代码的情况下返回到循环的开头?
只需使用一个内循环:
for (const character of string) {
while(true) {
const next = table.get(character);
if (next) {
[token, table] = next.value;
break;
} else if (token) {
yield token.value;
[token, table] = lexer;
// don't break, redo
} else {
throw new SyntaxError("Unexpected character", character);
break;
}
}
}
重启整个循环:
在你的例子中其实很简单:
yield* scan(lexer)(string);
return;
如果您不想重新启动整个功能,请添加一个 IIFE 并记住:
yield* (function redo*() {
//...
yield* redo();
return;
})();
如果你真的需要跳转,使用标签(请不要):
restart: while(true) {
// do stuff
continue restart;
//...
break;
}