【问题标题】:Distribute iterator items over subiterators在子迭代器上分配迭代器项
【发布时间】:2018-02-03 16:09:15
【问题描述】:

我正在使用 javascript 中的迭代器。我找到了一种链接它们的方法,因此我不必嵌套它们,只是为了便于阅读。

它的工作方式与数组映射链完全一样。

我喜欢做的是将生成器的项目分配给几个子迭代器,捕获结果并将它们提供给下一个迭代器。这样的结果将是这样的:

4
6
8
7
9
11

鉴于这段代码:

"use strict";

const _ = require('lodash');

let things = chain([
    gen,
    addOne,
    distribute([
        addOne,
        addTwo,
        addThree
    ]),
    addOne
]);

for(let thing of things) {
    console.log(thing);
}

//////////////// DEFENITIONS ////////////////////

function* gen() {
    yield* [1, 2, 3, 4, 5, 6];
}

function* addOne(iterator) {
    for(let item of iterator) {
        yield (item + 1)
    }
}

function* addTwo(iterator) {
    for(let item of iterator) {
        yield (item + 2)
    }
}

function* addThree(iterator) {
    for(let item of iterator) {
        yield (item + 3)
    }
}

const distribute = _.curry(function* (iterators, iterator) {
    // magic
});

function chain(iterators) {
    return iterators.reduce((prevIterator, thisIterator, index) => {
        if(index === 0) {
            return thisIterator();
        }
        return thisIterator(prevIterator);
    }, null);
}

最后我想在分布迭代器中添加一个分布函数,这样它就可以确定将哪个项目传递给哪个子迭代器。目前只是基于顺序。

问题:我如何编写一个分发迭代器,它将一些子迭代器作为参数并将结果传递给下一个迭代器。

【问题讨论】:

  • 对不起,我完全没有得到你想要 distribute 做的事情。
  • 对不起,如果我不清楚。生成器提供整数。我想将 1 和 4 发送到迭代器 addOne,将 2 和 5 发送到迭代器 addTwo,将 3 和 6 发送到迭代器 addTrhee
  • 啊,我明白了。所以你基本上想tee他们,然后将它们压缩/拼合在一起。
  • 嗯,我不熟悉 tee 的概念。我会读进去的。谢谢!

标签: javascript iterator generator chaining currying


【解决方案1】:

看起来过于复杂,但确实有效

const distribute = _.curry(function* (iterators, mainIterator) {
    let iteratorIndex = 0;
    let done = [];
    for(let iterator of iterators) {
        iterators[iteratorIndex] = iterator(mainIterator);
        done.push(false);
        iteratorIndex++;
    }
    while(true) {
        let iteratorIndex = 0;
        for(let iterator of iterators) {
            let next = iterator.next();
            done[iteratorIndex] = next.done;
            if(!next.done) {
                yield next.value;
            }
            iteratorIndex++;
        }
        if(done.every(done => done)) {
            return;
        }
    }
});

最后还有一个分布函数:

const distribute = _.curry(function* (genIteratorIndex, iterators, mainIterator) {
    let iteratorIndex = 0;
    let done = [];

    // instantiate iterators
    for(let iterator of iterators) {
        iterators[iteratorIndex] = iterator(mainIterator);
        done.push(false);
        iteratorIndex++;
    }

    // Pass stuff through
    while(true) {
        let next = iterators[genIteratorIndex.next().value].next();
        done[iteratorIndex] = next.done;
        if(!next.done) {
            yield next.value;
        }
        if(done.every(done => done === true)) {
            return;
        }
    }
});

function* subSequent(len) {
    let curr = 0;
    while(true) {
        if(curr === len) {
            curr = 0;
        }
        yield curr;
        curr++;
    }
}


let things = chain([
    gen,
    addOne,
    distribute(subSequent(3), [
        addOne,
        addTwo,
        addThree
    ]),
    addOne
]);

【讨论】:

    猜你喜欢
    • 2019-04-06
    • 2014-10-14
    • 1970-01-01
    • 2010-11-25
    • 2013-11-02
    • 2021-02-11
    • 2017-09-02
    • 2011-03-24
    • 2010-09-20
    相关资源
    最近更新 更多