我是clojure的新手,並在clojure文檔中注意到此示例。Clojure:具有減少的匿名函數
(reduce (fn [m [k v]] (assoc m v k)) {}{:b 2 :a 1 :c 3})
輸出:;;=> {2 :b, 1 :a, 3 :c}
可有人背後的代碼的邏輯解釋?
我是clojure的新手,並在clojure文檔中注意到此示例。Clojure:具有減少的匿名函數
(reduce (fn [m [k v]] (assoc m v k)) {}{:b 2 :a 1 :c 3})
輸出:;;=> {2 :b, 1 :a, 3 :c}
可有人背後的代碼的邏輯解釋?
reduce
將函數應用於累加器和序列中的每個元素,以建立最終結果。 ClojureDocs給出the signature for reduce爲(reduce f coll)
或(reduce f val coll)
。您的示例具有與元件匹配後者簽名如下:
f
:函數應用到每個條目,(fn [m [k v]] ...
val
:初始累加器,{}
coll
:操作上收集, {:b 2 :a 1 :c 3}
請注意,reduce調用的第二個參數和第三個參數之間沒有分隔符(即空格)。 Clojure不需要一個。
然後,看看內部的匿名函數:(fn [m [k v]] (assoc m v k))
。第一個參數m
是累加器的當前值,其在減少開始時爲{}
。 Destructuring syntax用於第二個參數,它是要修飾的當前值,即一個映射條目。地圖條目被拆解爲其關鍵字k
並且值v
。匿名函數的主體只是向累加器(即map)放入一個新的「反向」條目,以便原始序列v
的值是關鍵字,關鍵字k
成爲該值。結果類似於應用Clojure API函數map-invert。
請注意,有一個單獨的reduce-kv函數用於減少關聯集合(例如,地圖)。 reduce-kv
「爲你解構」。這允許將被寫入的匿名功能:
(fn [m k v] (assoc m v k))
或者甚至更簡單地與短符號:
#(assoc %1 %3 %2)
第一個映射是空的,它是一個可選的初始化值,它是傳遞給reduce函數的第一個參數。第二張地圖是要減少項目的集合。在這種情況下,每個項目是MapEntry
,並且它們作爲第二個參數一次傳遞給還原函數。
鑑於您的輸入地圖有三個鍵/值對,縮減功能將被調用三次。減號函數的參數m
參考第一次調用時的初始化值(空映射)和分解第二個參數k and v
來自在迭代中傳遞的MapEntry
對。
儘管大多數時候reduce函數在第一個參數被操作後返回第一個參數,但在您的示例中,它將第二個參數的鍵/值顛倒並將新對與初始化值相關聯,這樣做..
這意味着reduce
地圖{:b 2 :a 1 :c 3}
與功能(fn [m [k v]] (assoc m v k))
其依次取一個鍵 - 值對[k v]
從地圖上把它和accumulator hash-map m
關聯。累加器散列映射的初始狀態設置爲空({}
)。
您認爲這意味着什麼?你有什麼零件有麻煩? – amalloy
'{} {:b 2:a 1:c 3}' – Srini
@ user1702169將這兩幅貼圖「粘」在一起這樣並不真正有幫助(除非你是代碼打高爾夫球)。把它寫成「{} {...}」,這將是明確的,那是兩件不同的事情。 – cfrick