如何为Seq链接自定义操作并使其保持懒惰和流畅?

时间:2017-11-24 17:20:20

标签: javascript lodash

基于问题Create chain in lodash with custom functions我想根据以下要求链接我自己的自定义函数:

  1. 保持流利
  2. 返回Seq
  3. 保持懒惰行为
  4. 例如,考虑以下查询产生的序列res

    const src = [0, 1, 1, 6, 6, 6, 1, 1, 12, 12, 6, 6]
    const res = _(src)
        .filter(nr =>  nr % 2 == 0)
        .map(nr => 'nr:' + nr)
    console.log(res.value()) // => ['nr:0','nr:6','nr:6','nr:6','nr:12','nr:12','nr:6','nr:6' ]
    

    现在,我想在filter()map()之间进行交错,这是一个新的collapse()操作,它会合并一系列相邻元素。

    我正在实施这样的collapse()

    function collapse(src) {
        const res = []
        let prev = undefined
        for(let curr of src) {
            if(prev != curr) {
                prev = curr
                res.push(curr)
            }
        }
        return _(res)
    }
    

    但是这个解决方案不符合要求:1。保持流畅,3。保持懒惰的行为。要使用此collapse(),我们必须写:

    collapse(
        _(src)
        .filter(nr =>  nr % 2 == 0)
    )
    .map(nr => 'nr: ' + nr) // => [ 'nr: 0', 'nr: 6', 'nr: 12', 'nr: 6' ]
    

    相反,我想写一下:_(src).filter(nr => nr % 2 == 0).collapse().map(nr => 'nr: ' + nr)

    即使最糟糕的是,崩溃正在急切地进行。

    从这个answer我看到我们可以用mixin效用函数扩展lodash原型。但是,我不知道如何访问上一个操作的元素(例如filter())以便在collapse()函数中进行解析?

2 个答案:

答案 0 :(得分:1)

mixin将在链中工作,传递给函数的第一个参数将是上一个操作的结果:

_.mixin( { collapse: function(list){
    const res = []
    let prev = undefined
    for(let curr of list) {
        if(prev != curr) {
            prev = curr
            res.push(curr)
        }
    }
    return res;
}});

const res = _(src)
    .filter(nr =>  nr % 2 == 0)
    .collapse()
    .map(nr => 'nr:' + nr)
    .value();

答案 1 :(得分:0)

const collapse = start => el => el !== start ? ( start = el, true ) : false;

所以你可以这样做:

_(src).filter( collapse() )