【问题标题】:Two nested for of for and map?for和map的两个嵌套?
【发布时间】:2012-05-09 15:26:39
【问题描述】:

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

(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 for-loop clojure idioms


    【解决方案1】:

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

    嵌套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)
    

    【讨论】:

    • +1... 关于内置嵌套:我确实做了两个嵌套循环,然后是 flatten 以获得单个序列(而不是序列序列)。我现在明白了:我试图通过使用 #(...) 快捷方式嵌套两个 map,因此无处可去!
    【解决方案2】:

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

    您似乎正在尝试创建一个值为

    的值序列

    (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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 2020-03-04
      • 2021-03-02
      • 1970-01-01
      • 2021-09-15
      • 2019-02-18
      • 1970-01-01
      相关资源
      最近更新 更多