clojure中的稀疏填充多维向量?

clojure中的稀疏填充多维向量?,clojure,Clojure,我试图在Clojure中创建一个人口稀少的多维向量,但我的知识有限 我有一个正在迭代的集合x,我想通过(count x)创建一个大小为(count x)的多维向量。大多数单元格都是空的,但是在x轴和y轴匹配的每个点(例如,(1)、(2)、(3)等),我需要运行一个函数来查看是否应该在该空间中放置一个值 在程序语言中,它类似于: for (i = 0; i < length(x); i++) { for (j = 0; j < length(x); j++) {

我试图在Clojure中创建一个人口稀少的多维向量,但我的知识有限

我有一个正在迭代的集合
x
,我想通过
(count x)
创建一个大小为
(count x)
的多维向量。大多数单元格都是空的,但是在x轴和y轴匹配的每个点(例如,(1)、(2)、(3)等),我需要运行一个函数来查看是否应该在该空间中放置一个值

在程序语言中,它类似于:

for (i = 0; i < length(x); i++) {
    for (j = 0; j < length(x); j++) {
        if (i == j && testReturnsTrue(x[i])) {
            table[i][j] = (list x[i])
        }
        else {
            table[i][j] = ()
        }
    }
}
for(i=0;i
但我不知道在Clojure会怎么做。我尝试使用嵌套的理解结构和嵌套的循环递归结构,但两者都不起作用


或者,我可以创建一个具有正确大小的可变表,将其全部初始化为空列表,然后在检查
x
中的每个元素时设置值,但如果可能,我希望保持表不可变。

嵌套
for
s是我的做法:

(def x [:a :b :c :d])
(vec (for [i (range (count x))]
       (vec (for [j (range (count x))]
              (if (and (= i j) (identity (x i)))
                [(x i)]
                [])))))
=> [[[:a] [] [] []] [[] [:b] [] []] [[] [] [:c] []] [[] [] [] [:d]]]
(identity(xi))
是某种测试的替代品


编辑:如其他答案中所述,如果此结构仍然稀疏填充,则哈希映射是更好的选择。我假设您将在以后的计算中填充空部分。

使用hashmap?不需要向量,它不能是稀疏的。另外,这个必要的解决方案看起来也不是稀疏的——它是在浪费内存存储大量的空单元。也许是这样的:

(let [indexed (map-indexed vector xs)]
  (reduce (fn [m [i x]]
            (if (test? x)
              (assoc-in m [i i] x)
              m))
          {}
          indexed))

太好了,谢谢!我将填充表的其余部分,这只是第一次将数据放在对角线上。即使填充了其余部分,hashmap至少也是一样好的,除非您想按数字顺序迭代键。如果你所做的只是随机访问,我认为hashmap更清晰。FWIW你用“稀疏”这个词来表示某种显然让所有回答的人都感到困惑的东西。如果您的向量稍后将被填充,而现在只是稀疏的,那么面向稀疏的技术就没有多大意义。我建议你改变或澄清这个问题。