当我需要生成一个需要“两个循环”的序列时,最好这样做:
(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获得相同的结果?
两者都可以,但是第二个版本可以更好地扩展到任意嵌套级别。
嵌套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)
请记住for
,在 clojure 中不是“循环”,而是列表理解。我发现从所需值向后思考比从我的迭代方式向前思考更容易。
看来您正在尝试创建一个值序列,其中值是
(map #(* x %) y)
x
是1 >= 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))