首页 > 解决方案 > 使用传递值运行嵌套循环的惯用方式

问题描述

我想做这样的事情

int n=0
for(int i=xs; i<xe; i++){
  for(int j=ys; j<ye; j++){
    n++
  }
}
return n;

以 Clojure 方式。由于所有值都是不可变的,我认为值 n 应该作为(可能)递归函数的参数传递。最好的方法是什么?

标签: loopsclojurenested-loopsidiomscode-translation

解决方案


最接近您的代码的是

(defn f [xs xe ys ye]
  (let [n (atom 0)]
    (doseq [_ (range xs xe)
            _ (range ys ye)]
      (swap! n inc))
    @n))

user> (f 1 10 2 20)
;;=> 162

但是可变原子方法根本是单一的。

它可能看起来像这样,更像是clojure方式

(defn f [xs xe ys ye]
  (count (for [_ (range xs xe)
               _ (range ys ye)]
           nil)))
#'user/f

user> (f 1 10 2 20)
;;=> 162

这真的取决于你想要做什么。正如@jas 注意到的那样,计数 n 显然做得更好(* (- xe xs) (- ye ys)),与您使用的语言无关)

你提到的递归解决方案怎么样,它可能看起来像这样:

(defn f [xs xe ys ye]
  (loop [n 0 i xs j ys]
    (cond (== j ye) n
          (== i xe) (recur n xs (inc j))
          :else (recur (inc n) (inc i) j))))
#'user/f

user> (f 1 10 2 20)
;;=> 162

推荐阅读