如何在Clojure中修改矢量的一部分?

时间:2011-08-17 00:45:52

标签: clojure

我想知道我是否遗漏了一些涉及矢量操作的基本内容。假设我有以下内容:

(def xs [9 10 11 12 13]) 
(def idx [0 2]) 
(def values [1 3])

如果我想在Matlab中返回向量[1 10 3 12 13],我会写xs(idx) = values。 在Clojure中,有没有一种原始的方法来实现这一目标?现在我正在使用以下功能:

(defn xinto [seq idx val]
  (apply assoc seq (interleave idx val)))

感谢。

3 个答案:

答案 0 :(得分:8)

这有点尴尬因为你将idxvalues分成两个seq,当它们在概念上是一个索引到值的映射。因此,如果您允许我对您的数据格式进行一些创意修改:

(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

如果您以某种奇怪的方式生成idxvalues,将它们组合在一起并不方便,您可以稍后使用(map list idx values)对它们进行分组,然后使用我的xinto实施。

答案 1 :(得分:3)

我可能会使用reduce

(reduce 
  (fn [old [i v]] (assoc old i v))
   x   
  (map vector idx values))

但是,如果你真的想要这么做(Matlab风格)那么我建议创建一些辅助宏/函数来创建某种用于矢量操作的DSL。

答案 2 :(得分:2)

找不到更好的东西。

在核心序列函数中有replace,但它适用于值,而不适用于键。 所以,

(replace {9 2} x)

会返回

[2 10 11 12 13]

如果你打算在Clojure中做数学相关的事情,我也建议你看一下Incanter。它有很多API来操纵数学数据。