Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在clojure中同时更新两个值_Clojure_Update In - Fatal编程技术网

在clojure中同时更新两个值

在clojure中同时更新两个值,clojure,update-in,Clojure,Update In,我想知道如何同时更新两个值。例如,我想在增加月份的同时减少年龄。我的代码是 user=>(def users {:month 1 :age 26}) user=>(update-in users [:month :age] inc dec) 我知道这个语法是不正确的,但是我怎样才能解决这个问题呢?我需要同时更新。因为如果我先更新月份,然后更新年龄,那么当我更新第二个地图时,第一个地图将丢失。或者有其他方法解决这个问题吗?更新不修改值,它只返回一个新值,所以它只是一个函数。如果需要更

我想知道如何同时更新两个值。例如,我想在增加月份的同时减少年龄。我的代码是

user=>(def users {:month 1 :age 26})
user=>(update-in users [:month :age] inc dec)

我知道这个语法是不正确的,但是我怎样才能解决这个问题呢?我需要同时更新。因为如果我先更新月份,然后更新年龄,那么当我更新第二个地图时,第一个地图将丢失。或者有其他方法解决这个问题吗?

更新不修改值,它只返回一个新值,所以它只是一个函数。如果需要更新地图的两个字段,最简单的方法就是调用
update
两次,首先在原始地图上,然后在第一次更新的结果上:

(defn update-month-and-age [user]
  (update (update user :month inc) :age dec))
使用
->
哪个看起来更好:

(defn update-month-and-age [user]
  (-> user
      (update :month inc)
      (update :age dec)))

update
不修改值,它只返回一个新值,因此它只是一个函数。如果需要更新地图的两个字段,最简单的方法就是调用
update
两次,首先在原始地图上,然后在第一次更新的结果上:

(defn update-month-and-age [user]
  (update (update user :month inc) :age dec))
使用
->
哪个看起来更好:

(defn update-month-and-age [user]
  (-> user
      (update :month inc)
      (update :age dec)))
在这种简单的情况下(更新函数而不增加参数),您也可以这样做:

user> (def users {:month 1 :age 26 :records [1 2 3]})
#'user/users

user> (reduce-kv update users {:month inc :age dec :records reverse})
{:month 2, :age 25, :records (3 2 1)}
如果使用其他参数,则会更加详细:

user> (reduce-kv (partial apply update)
                 users
                 {:month [+ 2] :age [dec] :records [conj 101]})
{:month 3, :age 25, :records [1 2 3 101]}
嗯,这比简单使用线程宏更糟糕。

在这种简单的情况下(更新函数而不增加参数),您也可以这样做:

user> (def users {:month 1 :age 26 :records [1 2 3]})
#'user/users

user> (reduce-kv update users {:month inc :age dec :records reverse})
{:month 2, :age 25, :records (3 2 1)}
如果使用其他参数,则会更加详细:

user> (reduce-kv (partial apply update)
                 users
                 {:month [+ 2] :age [dec] :records [conj 101]})
{:month 3, :age 25, :records [1 2 3 101]}

嗯,这比简单使用线程宏更糟糕。

我试图通过编写一个函数来解决这个问题,该函数采用map:keyword->function,并生成一个将所有函数应用于相关记录/映射条目的函数

这样的功能是

(defn field-updater [fn-map]
  (fn [record]
    (reduce
     (fn [m [k f]] (assoc m k (f (m k))))
     record
     fn-map)))
我们使用它来生成所需的字段更新程序:

(def update-in-users (field-updater {:month inc :age dec}))
。。。然后我们可以申请

(update-in-users users)
;{:month 2, :age 25}

我试图通过编写一个函数来解决这个问题,该函数采用map:keyword->function,并生成一个将所有函数应用于相关记录/映射条目的函数

这样的功能是

(defn field-updater [fn-map]
  (fn [record]
    (reduce
     (fn [m [k f]] (assoc m k (f (m k))))
     record
     fn-map)))
我们使用它来生成所需的字段更新程序:

(def update-in-users (field-updater {:month inc :age dec}))
。。。然后我们可以申请

(update-in-users users)
;{:month 2, :age 25}

我同意你的第一个解决方案,它确实有效。但是对于第二个,我知道你想告诉我使用箭头符号更好,但是这个方法不适用于这个问题。因为在更新第二个更新时不会保存第一个更新。第一种方法的结果是
{:month 2:age 25}
。但是第二个结果是
{:month 1:age 25}
。谢谢你的帮助@秀芬许不,那不对
(更新月份和年龄{:month 1:age 26})
返回两种实现的
{:month 2:age 25}
用户>(macroexpand-1'(->用户(更新:month inc)(更新:age dec))=>(更新(更新用户:month inc):age dec)
@Elogent非常感谢!这是我的错,当我使用你的代码时,我写了一些错误。谢谢lot@ArthurUlfeldt非常感谢你!您的宏扩展非常清晰,我更容易理解。我同意您的第一个解决方案,它确实有效。但是对于第二个,我知道你想告诉我使用箭头符号更好,但是这个方法不适用于这个问题。因为在更新第二个更新时不会保存第一个更新。第一种方法的结果是
{:month 2:age 25}
。但是第二个结果是
{:month 1:age 25}
。谢谢你的帮助@秀芬许不,那不对
(更新月份和年龄{:month 1:age 26})
返回两种实现的
{:month 2:age 25}
用户>(macroexpand-1'(->用户(更新:month inc)(更新:age dec))=>(更新(更新用户:month inc):age dec)
@Elogent非常感谢!这是我的错,当我使用你的代码时,我写了一些错误。谢谢lot@ArthurUlfeldt非常感谢你!你的宏扩展非常清晰,我更容易理解。嗨,利奥!实际上,它应该是原子的,但我不认为有必要使用ref和dosync来解决这个问题。非常感谢你!因为clojure数据结构是不可变的,所以在这两个调用之间完全不可能更改数据。在Clojure中,对不可变集合的任何操作序列都是原子的!实际上,它应该是原子的,但我不认为有必要使用ref和dosync来解决这个问题。非常感谢你!因为clojure数据结构是不可变的,所以在这两个调用之间完全不可能更改数据。在Clojure中,对不可变集合的任何操作序列都是原子的。