如果我有一个简单的lodash链来映射,然后过滤一个数组:
lodash.chain(myarray)
.map(item=>{
if (item === 'some-condition') return [item];
})
.filter(item=>!!item)
.value();
显然,这是一个虚构的示例,但它与我一直以来所做的简单事情有关。基本上,数组映射不能返回某些映射,因此返回“ undefined”。然后,我过滤掉所有未定义的值。
由于它被大量使用,将它混入我的仪表板中是很有意义的。
所以:
const lodash = _.runInContext();
function mapFilter(ary, iterator) {
return lodash.chain(ary)
.map(iterator)
.filter(item=>!!item)
.value()
}
lodash.mixin(lodash, mapFilter, {chain:true});
很显然,我们可以做整件事而无需lodash,但通常,它可能是更大的链的一部分。从理论上讲,惰性评估可以使其更快。
我真正想要的是在我的混合方法中利用当前链(如果有)。否则,我将通过调用value()两次而失去惰性计算。
所以,如果我有更长的链条:
lodash.chain(myarray)
.mapFilter( // do something) // my bespoke chainable method
.map( // do something else )
.sort()
.value();
我想在我的定制方法中使用当前链(如果有)。像这样:
// This is made-up and does not work!
const lodash = _.runInContext();
function mapFilter(ary, iterator) {
if (!!this.__currentChain) {
return this.__currentChain.map(iterator).filter(item=>!!item);
}
return lodash.chain(ary)
.map(iterator)
.filter(item=>!!item)
.value()
}
lodash.mixin(lodash, mapFilter, {chain:true});
显然,以上内容是虚构的,但希望它可以使我清楚地了解要实现的目标。我当然可以,只是没有我的功能,先做一个map()然后再做一个filter(),但是由于我做了很多,所以我希望减少打字。另外,示例可能更长,要做的更多,但仍想利用当前的链。
这可能吗?那是我的问题。显然,我可以想到一百万种替代解决方案,但我对此表示满意。只是想找一个时髦的专家说,“不可能” ,或者“是的,你这样做”。。
答案 0 :(得分:1)
我将其发布为评论,但是我觉得这是您想要的,既可以作为插入内容,也可以作为您需要检查其执行方式的源代码,然后编写自己的方法或从中获取内容的一部分您的mixin等。
lodash _.tap method的目的是tap into" a method chain sequence in order to modify intermediate results
,因此您不必调用value
等。您可以以此为起点。
希望这会有所帮助。
答案 1 :(得分:1)
检查函数是否在链中被调用的一种方法是检查this
是否为LodashWrapper
对象。然后,将第一个参数用作链中的迭代器。
const _ = require('lodash');
const lodash = _.runInContext();
function mapFilter(array, iterator) {
if (this.constructor.name === 'LodashWrapper') {
return this.map(array).filter(item => !!item);
}
else {
return lodash.chain(array).map(iterator).filter(item => !!item).value();
}
}
lodash.mixin({ mapFilter }, { chain: true });
const filter = x => x == 2 ? [x] : null;
console.log(lodash.mapFilter([1, 2, 3], filter));
console.log(lodash.chain([1, 2, 3]).mapFilter(filter).head().value());
console.log(lodash([1, 2, 3]).mapFilter(filter).head());
顺便说一句,当您使用显式_.chain
时,lodash不会像您期望的那样应用快捷方式融合。因此,您可能需要使用隐式链接。有关详细信息,请参见Explicit chaining with lodash doesn't apply shortcut fusion。