2015-02-06 153 views
0

我有一個結構是這樣的:更新深度嵌套結構的Clojure

[["/1417612109-first-migration.clj" {:applied true :date-applied 1423233980}] 
["/1417612450-second-migration.clj" {:applied false}] 
["/1417615919-forth-migration.clj" {:applied false}]] 

我最終需要對其進行操作,並返回它的一個新版本。爲了找到這給了我,我後的矢量我需要處理我用filter價值和first,E.G:

["/1417612450-second-migration.clj" {:applied false}] 

我的問題是;我該如何更新地圖該特定項目,不必重新map在一大堆?我可以以某種方式將上述內容用作參考嗎?

+0

你需要':applied'?是否存在':date-applied'還不夠? – Thumbnail 2015-02-06 17:58:41

回答

3

如果您不需要作其他用途匹配的矢量返回,也就是說你只是爲了更新它,然後用地圖找到它,而不是過濾器和第一,他會檢查每個進入函數查看是否需要更新並根據需要返回已更改/未更改的條目。

(def test 
    [["/1417612109-first-migration.clj" {:applied true :date-applied 1423233980}] 
    ["/1417612450-second-migration.clj" {:applied false}] 
    ["/1417615919-forth-migration.clj" {:applied false}]]) 

(map #(if (:applied (second %)) 
     % ; if applied is already true then use it unchanged 
     (assoc-in % [1 :applied] true)) ; if applied is false update it 
    test) 

; (["/1417612109-first-migration.clj" {:applied true, :date-applied 1423233980}] 
; ["/1417612450-second-migration.clj" {:applied true}] 
; ["/1417615919-forth-migration.clj" {:applied true}]) 

如果你不需要外部集合是一個向量,那麼你可以使它成爲一個地圖,然後使用,例如, 「/1417612450-second-migration.clj」作爲重點assoc命令式或更新項。

(def test-map 
    {"/1417612109-first-migration.clj" {:applied true :date-applied 1423233980} 
    "/1417612450-second-migration.clj" {:applied false} 
    "/1417615919-forth-migration.clj" {:applied false}}) 

(def result ["/1417612450-second-migration.clj" {:applied false}]) 

(assoc-in test-map [(first result) :applied] true) 

;{"/1417612109-first-migration.clj" {:applied true, :date-applied 1423233980}, 
; "/1417612450-second-migration.clj" {:applied true}, 
;"/1417615919-forth-migration.clj" {:applied false}} 
0

您可以使用更新的功能https://clojuredocs.org/clojure.core/update-in

(update-in my-vector [0 1 :applied] f) 

其中f是一個函數,採用舊的值,並返回新的。這個例子會從你的第一個向量更新地圖中的應用值。它也適用於深層結構。更多信息請參閱文檔。

+0

謝謝你。我覺得麻煩在於,我不知道我找到的物品的索引是什麼。我已經有效地使用'(第一(過濾器...))'讓我從大的結構所需要的結構。 – 2015-02-06 15:12:33