Если у меня есть простая цепочка lodash, которая отображает, то фильтрует массив:
lodash.chain(myarray)
.map(item=>{
if (item === 'some-condition') return [item];
})
.filter(item=>!!item)
.value();
Очевидно, это составленный пример, но это связано с чем-то простым, что я делаю все время. В принципе, карта массива, где некоторые карты невозможны, так что "undefined" возвращается. Затем я отфильтровываю все неопределенные значения.
Поскольку он используется довольно много, имеет смысл смешивать его с моим lodash.
Так:
const lodash = _.runInContext();
function mapFilter(ary, iterator) {
return lodash.chain(ary)
.map(iterator)
.filter(item=>!!item)
.value()
}
lodash.mixin(lodash, mapFilter, {chain:true});
Очевидно, мы могли бы сделать все это без lodash, но обычно это может быть частью более крупной цепи. Теоретически, ленивая оценка делает это быстрее.
Я действительно хочу использовать текущую цепочку (если она есть) в моем смешанном методе. В противном случае, я теряю ленивую оценку, вызывая значение() дважды.
Итак, если у меня была более длинная цепочка:
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});
Очевидно, что вышесказанное составлено, но, надеюсь, оно дает понять, чего я пытаюсь достичь. Я мог бы, конечно, просто не иметь свою функцию и делать карту(), затем фильтр(), но, поскольку я делаю это много, я бы хотел иметь меньше набрав. Кроме того, пример может быть длиннее, делая гораздо больше, но все же желая использовать текущую цепочку.
Это возможно? Это мой вопрос. Очевидно, я могу думать о миллионах альтернативных решений, но я в порядке с ними. Просто ищите эксперта по lodash, чтобы сказать "невозможно", или "да, вы это делаете".
Один из способов проверить, вызвана ли функция в цепочке, - проверить, является ли 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 не применяет сочетание ярлыков, как вы могли ожидать. Поэтому вы можете использовать неявное цепочку. См. Раздел Явная цепочка с помощью lodash для детализации не применяет сочетание быстрого вызова.
Я разместил это как комментарий, но я чувствую, что это то, что вы хотели бы либо как падение или как что-то, что вам нужно, чтобы проверить источник, как это делается, а затем закодировать свой собственный метод или взять кусочки из него как часть вашего микса и т.п.
Метод lodash _.tap существует с целью tap into" a method chain sequence in order to modify intermediate results
чтобы вам не приходилось вызывать value
и т.д. Вы можете использовать это как отправную точку.
Надеюсь это поможет.