Вопрос по clojure – Clojure набор карт - базовая фильтрация

4

Clojure новичок здесь ..

Если у меня есть набор карт, таких как

 (def kids #{{:name "Noah" :age 5}
     {:name "George":age 3}
     {:name "Reagan" :age 1.5}})  

Я знаю, что могу получить такие имена

  (map :name kids)

1) Как выбрать конкретную карту? Например   Я хочу вернуть карту, где имя = "Рейган".

 {:name "Reagan" :age 1.5}

Можно ли это сделать с помощью фильтра?

2) Как насчет возвращения имени, где возраст = 3?

Ваш Ответ

2   ответа
8

filter:

(filter #(= (:name %) "Reagan") kids)

(filter #(= (:age %) 3) kids)
6

Там & APOS; sclojure.set/select:

(clojure.set/select set-of-maps #(-> % :age (= 3)))

И аналогично сname а также"Reagan", Возвращаемое значение в этом случае будет набором.

Вы также можете использоватьfilter без каких-либо специальных приготовлений, так какfilter звонкиseq на его аргументе коллекции(edit: as already described by ffriend while I was typing this):

(filter #(-> % :age (= 3))) set-of-maps)

Здесь возвращаемое значение будет ленивым seq.

Если вы знаете, что в наборе будет только один элемент, удовлетворяющий вашему предикату,some будет более эффективным (так как он не будет обрабатывать дополнительные элементы после нахождения соответствия):

(some #(if (-> % :age (= 3)) %) set-of-maps)

Возвращаемым значением здесь будет соответствующий элемент.

Правда, мне кажется, что я предпочитаю это как более самодокументируемый вариант (на мой взгляд, в любом случае).some все еще имеет преимущество для дорогих предикатов (из-за чанкинга).
Благодаря Lazy Seqs вы также можете сделать(first (filter … эффективно.

Похожие вопросы