georg georg - 1 year ago 78
Javascript Question

yield from a list of generators created from an array

I've got this recursive generator



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)])





It works fine, but I don't like the
for
part. Is there a way to write it functionally? I tried

if (Array.isArray(x))
yield *x.map(flat)


which didn't work.

Is there a way to write the above function without
for
loops?

Answer Source

You could use rest parameters ... and check the length of the rest array for another calling of the generator

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)])
.as-console-wrapper { max-height: 100% !important; top: 0; }

A similar approach but with a spread generator for calling the handed over generator with the spreaded values.

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)])
.as-console-wrapper { max-height: 100% !important; top: 0; }

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download