Цепочка тока цепным методом

1

Если у меня есть простая цепочка 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, чтобы сказать "невозможно", или "да, вы это делаете".

  • 0
    Карта с if - это редукция, фильтр undefined - это компакт. Ваша цепь может быть легко через сокращение
  • 0
    :-) ждал, что кто-то прокомментирует ... и фильтр-> карта будет лучше, чем карта-> фильтр. Это действительно, просто пример, что мне нужно было знать, как получить доступ к текущей цепочке.
Теги:
lazy-evaluation
lodash

2 ответа

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 не применяет сочетание ярлыков, как вы могли ожидать. Поэтому вы можете использовать неявное цепочку. См. Раздел Явная цепочка с помощью lodash для детализации не применяет сочетание быстрого вызова.

  • 0
    Спасибо, это именно то, что мне нужно. Кроме того, спасибо за информацию о _.chain () v _ (), я на самом деле, не знал об этом, и теперь есть некоторый рефакторинг, чтобы сделать!
1

Я разместил это как комментарий, но я чувствую, что это то, что вы хотели бы либо как падение или как что-то, что вам нужно, чтобы проверить источник, как это делается, а затем закодировать свой собственный метод или взять кусочки из него как часть вашего микса и т.п.

Метод lodash _.tap существует с целью tap into" a method chain sequence in order to modify intermediate results чтобы вам не приходилось вызывать value и т.д. Вы можете использовать это как отправную точку.

Надеюсь это поможет.

  • 0
    Спасибо, я взглянул на код, но на самом деле он просто передает вам массив, а не оболочку, но, как и вы, я подумал, что это может быть хорошим криком, учитывая то, что он делает.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню