I have two vectors:
(def x [true false true])
(def y [1 2 3])
I'd like to filter y
based on x
. My initial attempt is like so:
(remove nil? (map #(when %1 %2) x y))
which returns (1, 3)
as required.
My question is, is there a way I could have achieved the same result without having to filter out nils at the end? For example, I noticed keep
removes nils before returning, but it doesn't seem to accept multiple collections, like map does. Is there a more elegant way of filtering using a mask vector like above?
A vector is an associative collection from indices to items at those indices, so I'd use reduce-kv
:
(reduce-kv (fn [result idx item]
(cond-> result (x idx) (conj item)))
[] y)
There's also keep-indexed
that you can use as a transducer, but note that this approach will filter out any nil
s that might be present in the y
vector:
(into []
(keep-indexed (fn [idx item]
(when (x idx) item)))
y)