2011-06-28 81 views
4

我有我在REPL創建一個結構,追加到嵌套關聯結構

{1 {10 {:id 101, :name "Paul"}, 
    20 {}}, 
2 {30 {}, 40 {}}, 
3 {50 {}, 60 {}}} 

,我想一個新的KV添加到關鍵1,使得所得的結構是這樣的,

{1 {10 {:id 101, :name "1x2"}, 20 {}, 11 {:id 102, :name "Ringo"}}, 
2 {30 {}, 40 {}}, 3 {50 {}, 60 {}}}. 

我剛剛發現了像這樣嵌套結構的get-in update-in和assoc-in,但無法弄清楚如何在元素中添加新元素。在我的應用程序中,這是全部包裝在ref中,並用dosync/alter更新,但現在,我只想在REPL中做到這一點。

也許我剛纔看了太久,但任何嘗試使用assoc或assoc-in都會改變已存在的內容,並且不會添加新元素。

回答

7

鑑於你輸入

(def input 
    {1 {10 {:id 101 :name "Paul"} 
     20 {}} 
    2 {30 {} 40 {}} 
    3 {50 {} 60 {}}}) 

可以使用assoc命令式的元素與關鍵1添加到嵌套的地圖是這樣的:

(assoc-in input [1 11] {:id 102 :name "Ringo"}) 

這將產生

{1 {10 {:id 101 :name "Paul"} 
    11 {:id 102 :name "Ringo"} 
    20 {}} 
2 {30 {} 40 {}} 
3 {50 {} 60 {}}} 

Assoc-in不需要一直指向結構的最深層次。

如果使用兩個調用assoc命令,你可以使用第二個改名換姓「保」到「1×2」,按您的例子:

(assoc-in 
    (assoc-in input [1 11] {:id 102 :name "Ringo"}) 
    [1 10 :name] "1x2")) 

它返回

{1 {10 {:id 101 :name "1x2"} 
    11 {:id 102 :name "Ringo"} 
    20 {}} 
2 {30 {} 40 {}} 
3 {50 {} 60 {}}} 
+1

非常感謝。這是(assoc-in map [1 11] {}給我的,我假設矢量必須指向樹中的一個現有節點,這非常有幫助,並且找到所有這些* -in函數爲一個非常有趣的一天。 – JPT

+0

我很高興它是有用的。玩得開心學習!:) – Gert

1

如果您不得不指向現有節點,那麼爲了什麼值得您仍可以執行此操作:

(update-in input [1] assoc 11 
    {:id 102 :name "Ringo"})