5
votes

I am having a bit of difficulty with Lists in Clojure I have a quick question concerning the filter function

Let's say I have a List composed of Maps My code is:

(def Person {:name Bob } )
(def Person2 {:name Eric } )
(def Person3 {:name Tim } )
(def mylist (list Person Person2 Person3))

How would i go about filtering my list so that , for example: I want the list minus Person2 (meaning minus any map that has :name Eric)

Thank you very much to everybody helping me out. This is my last question I promise

3

3 Answers

18
votes

For this purpose, it's better to use the 'remove' function. It takes a sequence, and removes elements on which it's predicate returns 'true'. It's basically the opposite of filter. Here is an example of it, and filter's usage for the same purposes, that I worked up via the REPL.

user> (def m1 {:name "eric" :age 32})
#'user/m1
user> (def m2 {:name "Rayne" :age 15})
#'user/m2
user> (def m3 {:name "connie" :age 44})
#'user/m3
user> (def mylist (list m1 m2 m3))
#'user/mylist
user> (filter #(not= (:name %) "eric") mylist)
({:name "eric", :age 32})
user> (remove #(= (:name %) "eric") mylist)
({:name "Rayne", :age 15} {:name "connie", :age 44})

As you can see, remove is a little bit cleaner, because you don't have to use not=. Also, when working with maps, you don't have to use the 'get' function unless you want it to return something special if a key isn't in the map. If you know the key you're looking for will be in the map, there is no reason to use 'get'. Good luck!

5
votes

Suppose you have something like this:

(def Person {:name "Bob" } ) 
(def Person2 {:name "Eric" } ) 
(def Person3 {:name "Tim" } ) 
(def mylist (list Person Person2 Person3))

This would work:

(filter #(not= "Eric" (get % :name)) mylist)
0
votes

user=> (filter (fn [person] (not= (person :name) "Eric")) mylist) ({:name "Bob"} {:name "Tim"})

or using a more compact syntax:

user=> (filter #(not= (% :name) "Eric") mylist) ({:name "Bob"} {:name "Tim"})