THX1137
THX1137

Reputation: 973

What's the most idiomatic way to to remove collection elements with values containing one or more of a given collection of words?

Supposing I wanted to remove the list elements mentioning the animals in the banned-from-house collection:

(def list (atom [{:animal "a quick happy brown fox that rocks!"}
                 {:animal "a quick happy brown hamster that rocks!"}
                 {:animal "a quick happy brown bird that rocks!"}
                 {:animal "a quick happy brown dog and fox that rock!"}
                 {:animal "a quick happy brown fish that rocks!"}]))

(def banned-from-house (atom ["fox" "bird"]))

What would be the most idiomatic way to go about that?

Also, what would be a better title for this question? (I struggle in discussing clojure code)

Upvotes: 1

Views: 93

Answers (1)

Valentin Waeselynck
Valentin Waeselynck

Reputation: 6051

Let's build this step by step.

First, let's test if a String mentions some animal name, using clojure.string/includes?.

(defn mentions-animal? [s animal]
  (clojure.string/includes? s animal))

(mentions-animal?
  "a quick happy brown fox that rocks!"
  "fox")
=> true
(mentions-animal?
  "a quick happy brown fox that rocks!"
  "dog")
=> false 

Second, let's test if a string mentions some of a seq of animal names, using clojure.core/some.

(defn mentions-any? [s animals]
  (some #(mentions-animal? s %) animals))

(mentions-any?
  "a quick happy brown fox that rocks!"
  #{"fox" "dog"})
=> true
(mentions-any?
  "a quick happy brown fox that rocks!"
  #{"cat" "dog"})
=> nil

Next, extend this logic to animal maps instead of strings.

(defn animal-mentions-any? 
  [a animals]
  (mentions-any? (:animal a) animals))

Finally, implement the filtering logic using clojure.core/remove:

(defn remove-banned-animals 
  [animals-list banned-animals]
  (remove #(animal-mentions-any? % banned-animals) animals-list))

(remove-banned-animals
  [{:animal "a quick happy brown fox that rocks!"}
   {:animal "a quick happy brown hamster that rocks!"}
   {:animal "a quick happy brown bird that rocks!"}
   {:animal "a quick happy brown dog and fox that rock!"}
   {:animal "a quick happy brown fish that rocks!"}]
  ["fox" "bird"])
=> ({:animal "a quick happy brown hamster that rocks!"} {:animal "a quick happy brown fish that rocks!"})

Upvotes: 7

Related Questions