ES6发电机笛卡尔

时间:2018-10-10 06:05:59

标签: javascript

我具有计算笛卡尔组合的功能:

function cartes1(a, b, c) {
    let arr = []
    for (let i1 of a) {
        for (let i2 of b) {
            for (let i3 of c) {
                arr.push([i1, i2, i3])
            }
        }
    }
    return arr;
}

我想将其转换为生成器以在需要时停止,因此:

function* cartes(a, b, c) {
    for (let i1 of a) {
        for (let i2 of b) {
            for (let i3 of c) {
                yield [i1, i2, i3]
            }
        }
    }
}

代码基本相同,但是第二个返回错误结果。

cartes1([1,2,3],[1,2,3],[1,2,3]) // correct
cartes([1,2,3],[1,2,3],[1,2,3])

生成器返回以下内容:

[[ 1, 1, 1 ]
[ 1, 1, 2 ]
[ 1, 1, 3 ]]

生成器函数用

调用
cartes(range(1)(3)(1), range(1)(3)(1), range(1)(3)(1))
const range = from => to => function*(step=1) {
    for(let i=from;i<=to;i+=step) {
        yield i
    }
}

我想念什么吗?

谢谢

1 个答案:

答案 0 :(得分:2)

您要做的是使用三个生成器,但是一旦完成,就无法倒带它们。

为防止这种情况,您可以在收集的值上返回jzs闭包,并在for循环中第一次调用生成器。

如果通过直接使用此语句或在函数末尾达到了最后的done,则

Generator#next返回return

function*状态:

  

next()方法返回一个对象,该对象的value属性包含所产生的值和一个done属性,该属性指示生成器是否已将其最后一个值作为布尔值产生。用参数调用next()方法将恢复生成器函数的执行,并用next()中的参数替换暂停执行的yield表达式。

     

生成器中的return语句在执行时将使生成器完成(即,它返回的对象的done属性将设置为true)。如果返回一个值,它将被设置为生成器返回的对象的value属性。

     

就像return语句一样,在生成器内引发的错误将使生成器完成-除非捕获在生成器的主体内。

     

生成器完成后,后续的next调用将不会执行该生成器的任何代码,它们只会返回以下形式的对象:{value: undefined, done: true}由ns]

function* cartes(a, b, c) {
    for (let i1 of a()) {
        for (let i2 of b()) {
            for (let i3 of c()) {
                yield [i1, i2, i3];
            }
        }
    }
}

const range = from => to => (step = 1) => function* () {
    for (let i = from; i <= to; i += step) {
        yield i;
    }
};

for (let v of cartes(range(1)(3)(1), range(1)(3)(1), range(1)(3)(1))) {
    console.log(v);
}