开发者

How do I modify a portion of a vector in Clojure?

开发者 https://www.devze.com 2023-03-29 02:14 出处:网络
I am wondering if I\'m missing something basic involving vector manipulation. Let\'s say I开发者_运维问答 have the following:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号