如何在JavaScript中创建计数生成器/迭代器级联
How to create a counting generator/iterator cascade in JavaScript?
新版本的JavaScript允许将生成器/迭代器与yield
关键字结合使用。
我的问题背景
考虑下面的生成器,它产生"0 ~ 9的数字(数字):
// generator (produces numbers from 0 to 9, then stops)
function *zcounter() {
var i = 0;
while (i<=9) {
yield i;
i++;
}
}
现在我想用它来替换下面的函数,它使用3个嵌套的for
循环:
// e.g.: var iArray=[0,0,0];
function IterateCascade1(iArray) {
var iterations=0;
for (var x=0; x<=9; x++) {
iArray[0]=x;
for (var y=0; y<=9; y++) {
iArray[1]=y;
for (var z=0; z<=9; z++) {
iArray[2]=z;
logArray(iArray);
iterations++;
}
}
}
return iterations;
}
如果你像
那样调用上面的函数console.log("Iterations: "+IterateCascade1([0,0,0]));
然后它将从000到999数1000次,这正是我想要的。
缺点是只能使用包含3个元素的数组,不能传递包含更多元素的数组。
通过使用生成器zcounter()
来解决它,我尝试了以下操作:
// e.g.: var iArray=[0,0,0];
function IterateCascade2(iArray) {
var iterations=0;
// generate 3 iterators
var gArray = [];
for(var i=0; i<iArray.length; i++) {
var g=zcounter();
gArray[i]=g;
}
// loop through
for(var a in gArray) {
//console.log("a:"+a);
var g=gArray[a];
var gnext=g.next();
while (!gnext.done)
{
iArray[a]=gnext.value;
logArray(iArray);
gnext=g.next();
iterations++;
}
}
return iterations;
}
如果你像
那样调用上面的函数console.log("Iterations: "+IterateCascade2([0,0,0]));
那么它将只计数30次,并且它不会像IterateCascade1
那样遍历所有1000个数字。
此外,如果传递像
这样的大数组console.log("Iterations: "+IterateCascade2([0,0,0,0]));
则会"count"从0到9的每一个数字,但不会经过所有10000个组合。
我知道这里缺少一个递归。
- 如何修改
IterateCascade2
,使它做正确的事情(循环通过所有组合,你可以传递任何大小的整数数组)?
注意:
为了显示组合,我使用了
function logArray(x) {
var result="";
for(var i=0; i<x.length; i++) { result += x[i].toString(); }
console.log(result);
}
在上面的例子中。您可以使用3种浏览器中的任何一种开发人员工具或JSShell来运行代码。
这是一个递归的解决方案
function iterareIndex(index, array, iterator) {
var previousValue = array[index];
for (var i = 0; i < 10; ++i) {
array[index] = i;
if (index == array.length - 1) {
iterator(array);
} else {
iterareIndex(index + 1, array, iterator);
}
}
array[index] = previousValue;
}
function IterateCascade2(array){
iterareIndex(0, array, logArray);
}
顺便说一下,这将给你相同的输出,可能更短:
var size = 3;
var prefix = '';
for(var i = 0; i < size; ++i) {
prefix += '0';
}
for(var i = 0, l = Math.pow(10, 3); i < l; ++i){
var printableValue = (prefix+i).slice(-size);
console.log(printableValue);
}
相关文章:
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 从两个基于0的for循环迭代器中获取单个基于0的索引的公式
- Rails:试图在javascript(Google Charts API)中嵌入一个adv-ruby(each+迭代器
- 在javascript中,从迭代器创建Array
- Javascript中的迭代器和生成器
- 从迭代器/生成器中获取单个yield值
- 迭代器和可迭代之间的区别
- 文件夹迭代器中的Google驱动器文件迭代器
- DOM:如何根据迭代器值设置元素宽度并在mouseover上调用函数
- javascript中多维数组的迭代器
- 迭代Promise迭代器的非递归方法
- 循环中的Node.js回调具有错误的迭代器值
- underscore.js,迭代器引用错误
- 去掉foreach中的自定义绑定以获取迭代器
- 迭代器中的return element.parentNode
- 如何使用量角器+angular获取迭代器索引/键
- 在jquery each()迭代器函数中访问JS对象
- jQuery 改进表迭代器
- jquery map 数组在迭代器中返回 NaN
- 如何在JavaScript中创建计数生成器/迭代器级联