Функция не возвращается (Clojure)

Я новичок в clojure, моя функция, имеющая право голоса, не возвращает вектор, где я ошибаюсь.

(def human-db
  [
   {:name "Kanishk" :age 28 :sex "male"}
   {:name "Kanishk1" :age 29 :sex "male"}
   {:name "Kanishk2" :age 0 :sex "female"}
   {:name "Kanishk3" :age 1 :sex "male"}
   {:name "Kanishk4" :age 3 :sex "female"}
   {:name "Kanishk5" :age 3 :sex "male"}
   {:name "Kanishk6" :age 3 :sex "female"}
   {:name "Kanishk7" :age 3 :sex "male"}
   {:name "Kanishk8" :age 3 :sex "female"}])


(defn elligble-voters
  [human-db]
  (reduce (fn
            [new-map map]
            (if (> (:age map) 18)
              (conj new-map map)))  [] human-db))
(elligble-voters human-db)

person user2114063    schedule 10.08.2018    source источник
comment
Не могли бы вы уточнить, чего вы пытаетесь достичь?   -  person Aleph Aleph    schedule 10.08.2018
comment
у вас нет второй ветви if: если возраст меньше или равен 18, он просто возвращает nil . вместо этого вам нужно вернуть аккумулятор (new-map): (if ... (conj ...) new-map)   -  person leetwinski    schedule 10.08.2018


Ответы (2)


Проблема заключается в вашем выражении if - в нем нет пункта else, поэтому он возвращает ноль, когда избирателю меньше 18 лет.

Последний элемент в human-db имеет возраст 3, поэтому if возвращает nil, а сокращение возвращает nil.

Это работает:

(defn elligble-voters [human-db]
  (reduce (fn [new-map map]
            (if (> (:age map) 18)
              (conj new-map map)
              new-map)) ;; <-- Added `new-map` here
          []
          human-db))

Более аккуратный способ выразить ту же функцию будет таким:

(filter (fn [{:keys [age]}] (> age 18)) human-db)
person Marc O'Morain    schedule 10.08.2018

в то время как reduce, если вы можете делать то, что хотите, используйте что-то более подходящее для фильтрации коллекции.

i.e. filter

clojure.core/filter ([предыдущий] [предыдущий столбец])

Возвращает ленивую последовательность элементов в столбце, для которых (предыдущий элемент) возвращает логическое значение true. pred не должен иметь побочных эффектов. Возвращает преобразователь, если коллекция не предоставлена.


(defn elligble-voters [human-db]
  (filter #(> (:age %) 18) human-db))

#(> (:age %) 18) — это сокращение для анонимной функции, эквивалентное

(fn [x] 
  (> (:age x) 18))
person birdspider    schedule 10.08.2018