m0butt
m0butt

Reputation: 21

clojure: Removing maps from lazy-seq of maps

I have a lazy-seq of maps and I'm attempting to remove maps from that lazy-seq based on the return value from another function. The other function will return true or false depending on whether or not a call of get returns a value equal to the parameter. The problem is the function isn't working correctly and I'm not too sure why.

    (defn filter-by-name "Filter by names" [name m]
       (if (= name (get m :name_of_person)) true false)) 
        ;To be called on each map

    (defn remove-nonmatching-values "Remove anything not matching" [filter-val all-maps]
      (map #(remove (filter-by-name filter-val %)) all-maps)) 
       ;trying to call on the lazy seq

Upvotes: 0

Views: 343

Answers (2)

Thumbnail
Thumbnail

Reputation: 13473

A function that produces the test-function you need for a given name is

(defn name-matcher [name]
  (fn [m] (= name (:name_of_person m))))

All you have to do is filter the maps accordingly:

(defn retain-matching-maps [name maps]
  (filter (name-matcher name) maps))

For example,

(retain-matching-maps "hello" (list {:name_of_person "hello"} {:name_of_person "bye"}))
;({:name_of_person "hello"})

I have got rid of

  • the comments (which are implied by the function names)
  • the if (as noted by Guillermo)
  • the get (Keywords - or maps - are implicit get functions)
  • the double negative in the function name remove-nonmatching-values.

You could also use :name instead of :name-of-person. The more succinctly you express your program, the less likely you are to make mistakes.

Upvotes: 0

guilespi
guilespi

Reputation: 4702

You only need to call remove on the sequence of maps.

 (defn remove-nonmatching-values 
    "Remove anything not matching" 
    [filter-val all-maps]
    (remove #(filter-by-name filter-val %) all-maps))

Check Clojure's remove doc

(remove pred coll)

Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects. Returns a transducer when no collection is provided.

Upvotes: 1

Related Questions