I am wondering if I'm missing something basic involving vector manipulation. Let's say I have the following:
(def xs [9 10 11 12 13])
(def idx [0 2])
(def values [1 3])
If I want to return the vector [1 10 3 12 13]
in Matlab, I would write xs(idx) = values
.
In Clojure, is there a primitive way of achieving this? Right now I'm using the following function:
(defn xinto [seq idx val]
(apply assoc seq (interleave idx val)))
Thanks.
It's a bit awkward because you've split up idx
and values
into two seqs, when they're conceptually a map of indexes to values. So if you'll permit me a little creative modification of your data format:
(def x [9 10 11 12 13])
(def changes {0 1, 2 3})
(defn xinto [v changes]
(reduce (fn [acc [k v]]
(assoc acc k v))
v
changes))
(xinto x changes) ;; gets the result you want
If you generate idx
and values
in some weird way that it's not convenient to group them together, you can group them later with (map list idx values)
and then use my xinto
implementation with that.
I'd probably use reduce for this:
(reduce
(fn [old [i v]] (assoc old i v))
x
(map vector idx values))
However, if you really want to do this a lot (Matlab-style) then I'd suggest creating some helper macros / functions to create some kind of DSL for vector manipulation.
Could not find something better.
In the core sequence functions there is replace
, but it works on values, not on keys.
So,
(replace {9 2} x)
Would return
[2 10 11 12 13]
If you plan to do math related things in Clojure, I also propose you have a look at Incanter. It has a lot of APIs to manipulate mathematical data.
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