如果我们链接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()
不能保持快捷方式融合行为?
答案 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)
。
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);