Есть ли в Clojure редукционная функция, которая выполняет эквивалент `first`?
Я часто пишу код формы
(->> init
(map ...)
(filter ...)
(first))
При преобразовании этого кода в код, использующий преобразователи, я получу что-то вроде
(transduce (comp (map ...) (filter ...)) (completing #(reduced %2)) nil init)
Пишу (completing #(reduced %2))
вместо first
не очень хорошо со мной сидит Это излишне затеняет очень простую задачу. Есть ли более идиоматический способ выполнения этой задачи?
2 ответа
Я бы лично использовал ваш подход с пользовательской функцией сокращения, но вот несколько альтернатив:
(let [[x] (into [] (comp (map inc) (filter even?) (take 1)) [0 1])]
x)
Используя деструкцию:/
Или же:
(first (eduction (map inc) (filter even?) [0 1])
Здесь вы экономите на звонках comp
что сделано для вас. Хотя это не супер ленивый. Он будет реализовывать до 32 элементов, поэтому он потенциально расточителен. Исправлено с (take 1)
:
(first (eduction (map inc) (filter even?) (take 1) [0 1]))
В целом немного короче и не слишком непонятно по сравнению с:
(transduce (comp (map inc) (filter even?) (take 1)) (completing #(reduced %2)) nil [0 1])
Если вам нужна эта куча, то я бы, вероятно, НЕ создавал пользовательскую функцию редуктора, а вместо этого функцию, аналогичную преобразованию, которое принимает xform, coll
в качестве аргумента и возвращает первое значение. Понятнее, что он делает, и вы можете дать ему хорошую строку документации. Если вы хотите сэкономить на звонках comp
Вы также можете сделать его похожим на eduction
:
(defn single-xf
"Returns the first item of transducing the xforms over collection"
{:arglists '([xform* coll])}
[& xforms]
(transduce (apply comp (butlast xforms)) (completing #(reduced %2)) nil (last xforms)))
Пример:
(single-xf (map inc) (filter even?) [0 1])
попурри find-first
с преобразователем арности и Xforms имеет сокращающую функцию под названием last
, Я думаю, что комбинация двух - это то, что вам нужно.
(ns foo.bar
(:require
[medley.core :as medley]
[net.cgrand.xforms.rfs :as rfs]))
(transduce (comp (map ,,,) (medley/find-first ,,,)) rfs/last init)