Clojure中的数组和循环

时间:2018-05-03 14:22:11

标签: clojure

我正在尝试学习编程语言Clojure。我很难理解它。我想尝试实现像这样简单的东西(例如):

int[] array = new int[10];
array[0] =1; 
int n = 10; 

for(int i = 0; i <= n; i++){
    array[i] = 0; 
}
return array[n]; 

由于我是Clojure的新手,我甚至不了解如何实现这一点。如果有人可以解释或给出类似数组/ for循环在Clojure中如何工作的示例,那将会非常有用。我曾尝试做一些研究,但至于我的理解,Clojure并没有真正的for循环。

4 个答案:

答案 0 :(得分:6)

我认为@ Lee的答案中的最后一点应该重点强调。

除非出于性能原因绝对需要数组,否则你应该在这里使用向量。一旦开始使用本机Clojure结构,整个代码块就会变得微不足道:

; Create 10 0s, then put them in a vector
(vec (repeat 10 0))

如果您使用延迟序列而不是严格矢量,您甚至可以跳过对vec的调用。

还应注意,尽管将元素预初始化为0是不必要的。与数组不同,向量是可变长度的;它们可以在创建后添加和扩展。只需要一个空矢量并根据需要添加元素就更清晰了。

答案 1 :(得分:4)

编写你编写的Java for循环的Clojure方法是考虑你为什么要首先循环。将Java循环移植到Clojure有很多选项。选择它们取决于你的目标。

制作十个零的方法

正如Carcigenicate发布的那样,如果你在集合中需要十个零,请考虑:

(repeat 10 0)

返回sequence(一个lazy),这在Clojure中用于处理顺序值。如果需要通过索引访问十个零,请将它们放在带有:

的向量中
(vec (repeat 10 0))

(into [] (repeat 10 0))

或者,您可以直接在代码中编写矢量文字:

[0 0 0 0 0 0 0 0 0 0]

如果您出于某种原因特别需要 Java 数组,那么您可以使用to-array执行此操作:

(to-array (repeat 10 0))

但请记住the Clojure reference docs on Java interop的建议:

  

Clojure支持Java数组的创建,读取和修改[但]建议您限制使用数组来与需要它们作为参数的Java库交互或将它们用作返回值。

这些文档列出了一些用于处理Java数组的函数,主要是当它们需要Java互操作或支持变异或更高性能的操作时#34;。几乎在所有情况下,Clojurists都只使用矢量。

在Clojure中循环

如果您正在做除生产十个零之外的其他事情,该怎么办? Clojure方式转向&#34;循环&#34;取决于你需要什么。

你可能需要递归,Clojure有loop / recur

(loop [x 10]
  (when-not (= x 0)
    (recur (- x 2))

您可能需要为某些集合中的每个值计算的值

(for [x coll])
  (calculate-y x))

您可能需要迭代多个集合,类似于Java中的嵌套循环:

(for [x ['a 'b 'c] 
      y [1 2 3]]
  (foo x y))

如果您需要多次产生副作用,repeatedly就是您的果酱:

(repeatedly 10 some-fn)

如果您需要为集合中的每个值产生副作用,请尝试doseq

(doseq [x coll]
  (do-some-side-effect! x))

如果您需要为一系列整数产生副作用,可以使用doseq,如下所示:

(doseq [x (range 10)] 
  (do-something! x))

...但dotimesdoseq类似,内置range

(dotimes [x 9] 
  (do-something! x))

比那些循环结构更常见的是Clojure函数,它为集合中的每个元素生成一个值,例如map及其亲属,或者为了特殊目的而迭代集合(如{{1} }和filter)或创建一些新值或集合(如remove)。

答案 2 :(得分:2)

您可以在clojure中创建和修改数组,您的示例如下所示:

(defn example []
  (let [arr (int-array 10)
        n 10]
    (aset arr 0 1)
    (doseq [i (range (inc n))]
      (aset arr i 0))
    (aget arr n)))

请注意,此示例将引发异常,因为array[i]i = 10超出界限。

您通常会使用向量优先于数组,因为它们是不可变的。

答案 3 :(得分:0)

你可以在这里开个好头: