2015-02-06 104 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