Reputation: 35
I am new to clojure, my function elligble voters is not returning the vector, where am i going wrong.
(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)
Upvotes: 0
Views: 197
Reputation: 3074
while reduce
if capable of doing what you want, use something more suited for filtering a collection.
i.e. filter
clojure.core/filter ([pred] [pred coll])
Returns a lazy sequence of the items in coll for which (pred item) returns logical true. pred must be free of side-effects. Returns a transducer when no collection is provided.
(defn elligble-voters [human-db]
(filter #(> (:age %) 18) human-db))
#(> (:age %) 18)
is an shorthand for an anonymous function, equivalent to
(fn [x]
(> (:age x) 18))
Upvotes: 0
Reputation: 3759
The problem is with your if
expression - there is no else clause, so it is returning nil when the voter is aged less than 18.
The last item in human-db
is aged 3, so the if
returns nil
, and thus reduce returns nil
.
This works:
(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))
A neater way to express the same function would be like this:
(filter (fn [{:keys [age]}] (> age 18)) human-db)
Upvotes: 2