在clojure中人烟稀少的多维向量?

时间:2011-04-29 16:12:26

标签: clojure

我正在尝试在Clojure中创建一个人口稀疏的多维向量,但我正在反对我的知识极限。

我有一个集合x我正在迭代,我想通过(count x)创建一个大小为(count x)的多维向量。大多数单元格都是空的,但在x和y轴匹配的每个点(例如,(1 1),(2 2),(3 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] = ()
        }
    }
}

但我无法理解在Clojure中如何做到这一点。我尝试使用嵌套的for comprehensions和嵌套的循环重复结构,但我无法工作。

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

2 个答案:

答案 0 :(得分:11)

使用hashmap?不需要矢量,它不能稀疏。此外,这个必要的解决方案看起来也不稀疏 - 浪费内存储存数以万计的空单元格。也许是这样的:

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

答案 1 :(得分:4)

嵌套for是我的方式:

(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 (x i))是某种测试的替身。

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