jack
jack

Reputation:

How to remove multiple items from a list?

I have a list [2 3 5] which I want to use to remove items from another list like [1 2 3 4 5], so that I get [1 4].

thanks

Upvotes: 7

Views: 4180

Answers (4)

Nicolas Modrzyk
Nicolas Modrzyk

Reputation: 14197

You can do this yourself with something like:

(def a [2 3 5])
(def b [1 2 3 4 5])

(defn seq-contains? 
  [coll target] (some #(= target %) coll))

(filter #(not (seq-contains? a %)) b)
; (3 4 5)

A version based on the reducers library could be:

(require '[clojure.core.reducers :as r])

(defn seq-contains? 
 [coll target] 
   (some #(= target %) coll))

(defn my-remove
"remove values from seq b that are present in seq a"
 [a b]
 (into [] (r/filter #(not (seq-contains? b %)) a)))

(my-remove [1 2 3 4 5] [2 3 5] )
; [1 4]

EDIT Added seq-contains? code

Upvotes: 2

ᐅdevrimbaris
ᐅdevrimbaris

Reputation: 796

Here is my take without using sets;

(defn my-diff-func [X Y] 
   (reduce #(remove (fn [x] (= x %2)) %1) X Y ))

Upvotes: 0

Uros Dimitrijevic
Uros Dimitrijevic

Reputation: 2651

Try this:

(let [a [1 2 3 4 5]
      b [2 3 5]]
  (remove (set b) a))

which returns (1 4).

The remove function, by the way, takes a predicate and a collection, and returns a sequence of the elements that don't satisfy the predicate (a set, in this example).

Upvotes: 18

Ionuț G. Stan
Ionuț G. Stan

Reputation: 179219

user=> (use 'clojure.set)
nil
user=> (difference (set [1 2 3 4 5]) (set [2 3 5]))
#{1 4}

Reference:

Upvotes: 6

Related Questions