为什么lodash drop()操作不支持快捷方式融合?

时间:2017-11-22 17:10:03

标签: javascript lodash

如果我们链接filter()take()操作,我们将获得预期的快捷方式融合行为,其中过滤谓词仅针对满足所采用元素数量所必需的多个项目执行。在下面的示例中,要获取3个元素,我们可以检查过滤谓词仅执行5次(而不是10,这是src中元素的数量):

const src = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const res = _(src)
    .filter(nr => {
        console.log('Filtering...')
        return nr % 2 == 0
    })
    .take(3)
    .value()
console.log(res)

但是,如果我们在drop(1)filter()之间交错take(),那么它将导致src的所有元素的整个遍历。

const src = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const res = _(src)
    .filter(nr => {
        console.log('Filtering...')
        return nr % 2 == 0
    })
    .drop(1)
    .take(3)
    .value()
console.log(res)

在这种情况下,消息Filtering…打印10次。

为什么drop()不能保持快捷方式融合行为?

1 个答案:

答案 0 :(得分:1)

据我所知,drop方法会创建第二级LazyWrapper,其值__filtered__ = false会导致链式take方法创建一个新的view方法__takeCount__而不是更新有助于限制.filter方法执行的迭代次数的const src = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] const res = _(src) .filter(nr => { console.log('Filtering...') return nr % 2 == 0 }) .take(4) .drop(1) .value() console.log(res)

你可以Fiddle for Reference

filter

这将导致.take(3)的迭代次数减少,但会增加复杂性。

编辑:删除了无关的// Add `LazyWrapper` methods for `_.drop` and `_.take` variants. arrayEach(['drop', 'take'], function(methodName, index) { LazyWrapper.prototype[methodName] = function(n) { n = n === undefined ? 1 : nativeMax(toInteger(n), 0); var result = (this.__filtered__ && !index) ? new LazyWrapper(this) : this.clone(); if (result.__filtered__) { result.__takeCount__ = nativeMin(n, result.__takeCount__); } else { result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); } return result; }; LazyWrapper.prototype[methodName + 'Right'] = function(n) { return this.reverse()[methodName](n).reverse(); }; }); 电话,因为没有必要。

相关代码:

        rtbx_COMMENTS.Document.Blocks.Clear();
        rtbx_COMMENTS.AppendText(_x.COMMENT);