gpt4 book ai didi

clojure - 在 Clojure 的嵌套映射中关联多个键/值的惯用方法是什么?

转载 作者:行者123 更新时间:2023-12-02 05:46:10 25 4
gpt4 key购买 nike

假设您有一张这样的 map :

(def person {
:name {
:first-name "John"
:middle-name "Michael"
:last-name "Smith" }})

在一个表达式中更改与 :first-name 和 :last-name 关联的值的惯用方法是什么?

(澄清:假设您想将 :first-name 设置为“Bob”,将 :last-name 设置为“Doe”。我们还假设此映射中还有一些我们想要保留的其他值,因此构建从头开始不是一个选择)

最佳答案

这里有几种方法。

user> (update-in person [:name] assoc :first-name "Bob" :last-name "Doe")
{:name {:middle-name "Michael", :last-name "Doe", :first-name "Bob"}}

user> (update-in person [:name] merge {:first-name "Bob" :last-name "Doe"})
{:name {:middle-name "Michael", :last-name "Doe", :first-name "Bob"}}

user> (update-in person [:name] into {:first-name "Bob" :last-name "Doe"})
{:name {:middle-name "Michael", :last-name "Doe", :first-name "Bob"}}

user> (-> person
(assoc-in [:name :first-name] "Bob")
(assoc-in [:name :last-name] "Doe"))
{:name {:middle-name "Michael", :last-name "Doe", :first-name "Bob"}}

编辑

update-in 在 map 上执行递归 assoc。在这种情况下,它大致相当于:

user> (assoc person :name 
(assoc (:name person)
:first-name "Bob"
:last-name "Doe"))

当您深入一系列嵌套映射时,键的重复变得越来越乏味。 update-in 的递归可以让您避免一遍又一遍地重复键(例如 :name);递归调用之间的中间结果存储在堆栈中。看看 update-in 的来源看看它是如何完成的。

user> (def foo {:bar {:baz {:quux 123}}})
#'user/foo

user> (assoc foo :bar
(assoc (:bar foo) :baz
(assoc (:baz (:bar foo)) :quux
(inc (:quux (:baz (:bar foo)))))))
{:bar {:baz {:quux 124}}}

user> (update-in foo [:bar :baz :quux] inc)
{:bar {:baz {:quux 124}}}

assoc 是动态的(update-inassoc-in 以及大多数其他在 Clojure 数据结构上运行的 Clojure 函数也是如此) 。如果 assoc 到 map 上,它会返回一个 map 。如果您assoc到一个向量上,它会返回一个向量。查看 assoc 的来源并查看 Clojure 源代码中的 RT.java 了解详细信息。

关于clojure - 在 Clojure 的嵌套映射中关联多个键/值的惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4495345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com