从数组创建的生成器列表中获取

geo*_*org 13 javascript yield generator ecmascript-6

我有这个递归发生器

var obj = [1,2,3,[4,5,[6,7,8],9],10]

function *flat(x) {
    if (Array.isArray(x))
        for (let y of x)
            yield *flat(y)
    else
        yield 'foo' + x;

}

console.log([...flat(obj)])
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我不喜欢这for部分.有没有办法在功能上写它?我试过了

if (Array.isArray(x))
   yield *x.map(flat)
Run Code Online (Sandbox Code Playgroud)

这没用.

有没有办法在没有for循环的情况下编写上述函数?

Nin*_*olz 3

您可以使用剩余参数...并检查剩余数组的长度,以便再次调用生成器

function* flat(a, ...r) {
    if (Array.isArray(a)) {
        yield* flat(...a);
    } else {
        yield 'foo' + a;
    }
    if (r.length) {
        yield* flat(...r);
    }
}

var obj = [1, 2, 3, [4, 5, [6, 7, 8], 9], 10];
console.log([...flat(obj)])
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

类似的方法,但使用spread生成器来使用扩展值调用移交的生成器。

function* spread(g, a, ...r) {
    yield* g(a);
    if (r.length) {
        yield* spread(g, ...r);
    }
}

function* flat(a) {
    if (Array.isArray(a)) {
        yield* spread(flat, ...a);
    } else {
        yield 'foo' + a;
    }
}

var obj = [1, 2, 3, [4, 5, [6, 7, 8], 9], 10];
console.log([...flat(obj)])
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)