4

当我需要生成一个需要“两个循环”的序列时,最好这样做:

(for [x (range 1 4)] (map #(* x %) (range 6 9)))

或类似的东西:

(for [x (range 1 4)] (for [y (range 6 9)] (* x y)))

两者都给出相同的结果:

((6 7 8) (12 14 16) (18 21 24))

一个比另一个更惯用吗?这两者之间有什么区别?

另外,是否可以通过嵌套两个map获得相同的结果?

4

2 回答 2

8

两者都可以,但是第二个版本可以更好地扩展到任意嵌套级别。

嵌套map调用也有效:

user=> (map (fn [x] (map (fn [y] (* x y)) (range 6 9))) (range 1 4))
((6 7 8) (12 14 16) (18 21 24))

但是,您不能嵌套快捷函数语法。

顺便说一句,以防万一您确实需要更多类似集合理解的语义,for还内置了嵌套。结果有些不同:

user=> (for [x (range 1 4), y (range 6 9)] (* x y))
(6 7 8 12 14 16 18 21 24)
于 2012-04-29T19:14:49.423 回答
2

请记住for,在 clojure 中不是“循环”,而是列表理解。我发现从所需值向后思考比从我的迭代方式向前思考更容易。

看来您正在尝试创建一个值序列,其中值是

(map #(* x %) y)

  • x1 >= x > 4 =>(range 1 4)
  • y, 是(range 6 9)=>(repeat (range 6 9))

但是由于您希望终止理解,因此您需要调整y给予

  • y->[(range 6 9)]

最后作为一个惯用的列表理解(注意这与你的第一个例子非常相似,所以你几乎在那里)

(for [x (range 1 4) y [(range 6 9)]] (map #(* x %) y))
((6 7 8) (12 14 16) (18 21 24))
于 2012-04-30T08:35:54.317 回答