簡體   English   中英

clojure for循環,將值存儲在集合或映射中

[英]clojure for loop, store the values in a set or map

這個一直困擾我一段時間,我們應該如何在for循環中的集合或映射中存儲值?

(let [s #{}]
     (for [ i (range 10)
            j (range 10) ]
      (into s [i j])))

我知道這不起作用,但我想要一個與此類似的功能,其中集合最終將包含[0 0] [0 1] ... [0 9] [1 0] ... [9 9]

謝謝

如果我正確理解你的問題,你需要將你的表達從內到外:

(let [s #{}]
  (into s (for [i (range 10) 
                j (range 10)] 
            [i j])))

在這里實現的事情是, for不同於像Java和C更命令式語言的for循環返回一個值(一個懶惰的序列)

這是你想要的嗎?

(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]...

如果您只想將列表作為一組:

(set (for [i (range 10) j (range 10)]
  [i j]))    

你最終會得到一組對。

一般來說 ,當你想返回一組或一個地圖或其他“單值”,是不是從一個序列一“重復”廣義操作的序列,使用reduce是更地道/直白比loop/recur ,並for總回報seq(不是集合或映射)。

(reduce conj #{} (for [i (range 10) j (range 10)] [i j]))

請注意,(for ..)此處僅用於生成包含要編譯到單個結果集中的所有值的seq。 或者,例如:

(reduce + 0 (range 100))
=> 4950

clojure有幾個很好的系統來管理可變狀態。 在這種情況下,您可能需要一個包含集合的原子

你的其他選擇是:

  • 如果需要進行多次更改,則為ref (協調多個線程)
  • 一個變種 ,如果這將是單線程(一個變種可以很好的工作這里作為一個原子)
  • 如果要異步設置s的值,則為代理

當然for你可能只想要返回一個序列

 (into #{} (for [ i (range 10)
                  j (range 10) ]
             [i j]))

我認為在這種情況下你也可以使用一些瞬態數據結構。

(let [s (transient #{})]
 (for [ i (range 10)
        j (range 10) ]
  (assoc! s i j)))
(persistent! s)

只是一個代碼示例,未經過測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM