I have a one-dimensional vector, a vector of indices to update within the vector, and a value which should be associated with each of these indices.
I'm new to Clojure, and imagine that there might be a more idiomatic way to write the routine that I ended up with:
(defn update-indices-with-value [v indices value]
(loop [my-v v
my-indices indices
my-value value]
(if (empty? my-indices)
my-v
(recur (assoc my-v (peek my-indices) my-value)
(pop my-indices)
my-value))))
I know that assoc can be used to update multiple keys or indices within an associative collection, but I couldn't figure out the syntactic magic to use assoc with an arbitrary list of keys or indices.
Use reduce
:
(defn assoc-all
[v ks value]
(reduce #(assoc %1 %2 value) v ks))
Example:
(assoc-all [1 2 3 4] [0 1] 2)
;; => [2 2 3 4]
Alternatively, create the key/value pairs and use apply
:
(defn assoc-all
[v ks value]
(->> (interleave ks (repeat value))
(apply assoc v)))
If assoc
was using transients internally this might actually be more efficient than the reduce
version. Since it isn't, the lazy sequence overhead is probably eating it all up.
So, finally, a transient version:
(defn assoc-all
[v ks value]
(persistent!
(reduce
#(assoc! %1 %2 value)
(transient v)
ks)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With