clojure for循环,将值存储在集合或映射中

KaK*_*aKa 8 loops functional-programming clojure immutability

这个一直困扰我一段时间,我们应该如何在for循环中的集合或映射中存储值?

(let [s #{}]
     (for [ i (range 10)
            j (range 10) ]
      (into s [i j])))
Run Code Online (Sandbox Code Playgroud)

我知道这不起作用,但我想要一个与此类似的功能,其中集合最终将包含[0 0] [0 1] ... [0 9] [1 0] ... [9 9]

谢谢

Jon*_*nas 14

如果我正确理解你的问题,你需要将你的表达从内到外:

(let [s #{}]
  (into s (for [i (range 10) 
                j (range 10)] 
            [i j])))
Run Code Online (Sandbox Code Playgroud)

这里要实现的是for返回一个值(一个惰性序列),而不像Java和C等更多命令式语言中的for循环.


pon*_*zao 6

这是你想要的吗?

(into #{} (for [i (range 10) j (range 10)]
  [i j]))
;-> #{[2 1] [3 2] [4 3] [5 4] [6 5] [7 6] [8 7] [9 8] [1 0]
;     [2 2] [3 3] [4 4] [5 5] [6 6]...
Run Code Online (Sandbox Code Playgroud)

如果您只想将列表作为一组:

(set (for [i (range 10) j (range 10)]
  [i j]))    
Run Code Online (Sandbox Code Playgroud)

你最终会得到一组对.


Joo*_*aat 5

通常当你想要从seq上的'重复'广义操作返回一个集合或一个映射或其他不是seq的'单值'时,使用的reduce是更惯用/直接的loop/recur,并且for总是返回一个seq(不是设置或映射).

(reduce conj #{} (for [i (range 10) j (range 10)] [i j]))
Run Code Online (Sandbox Code Playgroud)

请注意,(for ..)此处仅用于生成包含要编译到单个结果集中的所有值的seq .或者,例如:

(reduce + 0 (range 100))
=> 4950
Run Code Online (Sandbox Code Playgroud)