Search code examples
clojure

How to filter a sequence and retain evaluated pred values?


This is a scenario I encountered many times, yet didn't find an idiomatic approach for it...

Suppose one would like to use a self-defined self-pred function to filter a seq. This self-pred function returns nil for unwanted elements, and useful information for wanted elements. It is desirable to keep the evaluated self-pred values for these wanted elements.

My general solution is:

;; self-pred is a pred function which returns valuable info
;; in general, they are unique and can be used as key
(let [new-seq (filter self-pred aseq)]
   (zipmap (map self-pred new-seq) new-seq))

Basically, it is to call self-pred twice on all wanted elements. I feel it is so ugly...

Wonder if there is any better ways. Much appreciated for any input!


Solution

  • i use this kind of snippet:

    (keep #(some->> % self-pred (vector %)) data)
    

    like this:

    user> (keep #(some->> % rseq (vector %)) [[1 2] [] [3 4]])
    ;;=> ([[1 2] (2 1)] [[3 4] (4 3)])
    

    or if you like more verbose result:

    user> (keep #(some->> % rseq (hash-map :data % :result)) [[1 2] [] [3 4]])
    ;;=> ({:result (2 1), :data [1 2]} {:result (4 3), :data [3 4]})