在Clojure中使用2D数组并初始化每个单元格的正确形式

JPT*_*JPT 5 clojure

(Lisp初学者)我需要创建一个2D数组,并初始化数组中的每个单元格.使用基于前一单元格中的数据的函数初始化每个单元.因此,将使用函数的结果初始化作为0,1的单元格,该函数使用来自单元格0,0的数据,依此类推.

我想知道设置这样的数据结构的正确的clojure习语是什么.

ffr*_*end 11

数组的表示实际上取决于您使用它的需要,而不是初始化它.例如,如果你有密集矩阵,你很可能应该使用这样的向量向量:

[[0, 1, 2, 3, 4],
 [5, 6, 7, 8, 9],
 [9, 8, 7, 6, 5],
 [4, 3, 2, 1, 0],
 [0, 1, 2, 3, 4]]
Run Code Online (Sandbox Code Playgroud)

或单个向量与原始长度的一些额外信息:

{:length 5
 :data
 [0, 1, 2, 3, 4, 
 5, 6, 7, 8, 9,
 9, 8, 7, 6, 5, 
 4, 3, 2, 1, 0, 
 0, 1, 2, 3, 4]
}
Run Code Online (Sandbox Code Playgroud)

如果你需要稀疏矩阵,你可以使用hash-maps:

{0 {0 0, 4 4},
 2 {2 7},
 3 {0 4, 2 2}}
Run Code Online (Sandbox Code Playgroud)

(因为你的2D数组很小,你根据之前的数据生成下一个值,我相信第一个选项更适合你).

如果要进行大量特定于矩阵的操作(乘法,分解等),您可能需要使用一些现有的库,如Incanter.

至于填充,我的建议是使用瞬态并存储中间结果,即(对于一维向量):

(defn make-array [initial-value f length]
  (loop [result (transient []), length-left length, interim-value initial-value]
    (if (= length-left 0)
        (persistent! result)
        (recur (conj! result (f interim-value)) (- length-left 1) (f interim-value))))
Run Code Online (Sandbox Code Playgroud)

瞬态将避免在每个新元素上创建新的数据结构,并且临时值将避免从瞬态结构中读取先前元素.