如何在Clojure中替换Java嵌套for循环?

del*_*ber 12 clojure

我创建了一个非常简单的嵌套循环示例,并且正在努力编写等效的Clojure代码.我一直试图通过列表推导来做到这一点,但无法得到相同的答案.任何帮助赞赏.

public class Toy {

    public static void main(String[] args) {
        int maxMod = 0;
        for (int i=0;i<1000;i++) {
            for (int j=i;j<1000;j++) {
                if ((i * j) % 13 == 0 && i % 7 == 0) maxMod = i * j;
            }
        }
        System.out.println(maxMod);
    }
}
Run Code Online (Sandbox Code Playgroud)

dno*_*len 23

这是一个列表理解解决方案:

(last 
  (for [i (range 1000) 
        j (range 1000)
        :let [n (* i j)] 
        :when (and (= (mod n 13) 0) 
                   (= (mod i 7) 0))] 
    n))
Run Code Online (Sandbox Code Playgroud)

  • @Bill`for`返回一个懒惰的seq,而`doseq`执行身体多次(大概是副作用)并返回nil (3认同)

Ret*_*ief 7

通常,您希望使用某种顺序操作(如dnolen的答案).但是,如果您需要执行某些序列函数组合中无法表达的内容,则使用loop宏也可以.对于这个精确的问题,dnolen的答案比任何使用的都好loop,但为了说明的目的,这里是你如何写它loop.

(loop [i 0
       max-mod 0]
  (if (>= i 1000)
    (println max-mod)
    (recur (inc i)
           (loop [j 0
                  max-mod max-mod]
             (if (>= j 1000)
               max-mod
               (recur (inc j)
                      (if (and (= (mod (* i j) 13) 0)
                               (= (mod 1 7) 0))
                        (* i j)
                        max-mod)))))))
Run Code Online (Sandbox Code Playgroud)

这几乎是您给定代码的精确翻译.也就是说,这显然是丑陋的,这就是为什么for尽可能使用(或其他类似功能)的解决方案的原因.