Anton Harald
Anton Harald

Reputation: 5954

Clojure: pass value if it passes predicate truth test

Is it possible to remove the let statement / avoid the intermediate 'x' in the following code?:

(let [x (f a)]
   (when (pred? x) x))

I bumped into this problem in the following use case:

(let [coll (get-collection-somewhere)]
   (when (every? some? coll)  ; if the collection doesn't contain nil values
      (remove true? coll)))   ; remove all true values

So if the collection is free of nil values, only not-true values remain, like numbers, strings, or whatever.

So, I'm looking for something like this:

(defn pass-if-true [x pred?]
   (when (pred? x) x))

Upvotes: 0

Views: 288

Answers (2)

johnbakers
johnbakers

Reputation: 24771

The let form is necessary to prevent your collection-building function from running twice:

(f a) or (get-collection-somewhere)

This is a typical idiom and you are doing it correctly.

Of course, you don't need the let if you already have the collection and are not building inside this expression.

However, you may wish to see when-let:

https://clojuredocs.org/clojure.core/when-let

It can save some keystrokes in some circumstances, but this isn't one of them.

Upvotes: 1

Sam Estep
Sam Estep

Reputation: 13354

Assuming that you don't want to define that pass-if-true function, the best you can do is an anonymous function:

(#(when (every? some? %)
    (remove true? %))
 (get-collection-somewhere))

You could also extract the predicate and transformation into parameters:

(#(when (%1 %3) (%2 %3))
 (partial every? some?)
 (partial remove true?)
 (get-collection-somewhere))

Upvotes: 1

Related Questions