如何在中使用assoc更新映射中的多个值?(Clojure)

如何在中使用assoc更新映射中的多个值?(Clojure),clojure,clojurescript,Clojure,Clojurescript,我正在尝试更新每一行有“享受clojure?”的内容,该内容将真实的“理智评级”返回到-2(即johnny的理智评级将更新为-2) 我是Clojure新手,曾尝试研究update和assoc,但似乎无法找到更新多个元素的方法((assoc学生数据库[0:SanityRating]-2)仅返回一个元素的更新)。要筛选学生数据库以取出返回true的学生,我有 (defn unhinged? [record] (:enjoy-clojure? record)) (defn minus-two-s

我正在尝试更新每一行有“享受clojure?”的内容,该内容将真实的“理智评级”返回到-2(即johnny的理智评级将更新为-2)

我是Clojure新手,曾尝试研究update和assoc,但似乎无法找到更新多个元素的方法(
(assoc学生数据库[0:SanityRating]-2)
仅返回一个元素的更新)。要筛选学生数据库以取出返回true的学生,我有

(defn unhinged?
 [record]
 (:enjoy-clojure? record))

(defn minus-two-students
 [student-database]
 (filter #(unhinged? %)
  (map student-database [0 1 2 3 4])))
返回

({:enjoy-clojure? true, :name "johnny", :sanity-rating 2} {:enjoy-clojure? 
   true, :name "jilly", :sanity-rating 5} {:enjoy-clojure? true, :name 
   "janey", :sanity-rating 8})

这很好,但我也需要它来更新他们所有的理智评级为-2。如有任何帮助/提示,将不胜感激

现在是
reduce kv
版本

(defn adjust-sanity [student]
  (if (:enjoy-clojure? student)
    (assoc student :sanity-rating -2)
    student))

(reduce-kv (fn [m k v] (assoc m k (adjust-sanity v)))
           {}
           student-database)
=>
{0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9},
 1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2},
 2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2},
 3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2},
 4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
或另一个带有辅助函数的选项,用于更新地图的所有值:

(defn update-vals [m f]
  (reduce-kv (fn [m' k v] (assoc m' k (f v))) {} m))
(update-vals student-database adjust-sanity)

下面是
reduce kv
版本

(defn adjust-sanity [student]
  (if (:enjoy-clojure? student)
    (assoc student :sanity-rating -2)
    student))

(reduce-kv (fn [m k v] (assoc m k (adjust-sanity v)))
           {}
           student-database)
=>
{0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9},
 1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2},
 2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2},
 3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2},
 4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
或另一个带有辅助函数的选项,用于更新地图的所有值:

(defn update-vals [m f]
  (reduce-kv (fn [m' k v] (assoc m' k (f v))) {} m))
(update-vals student-database adjust-sanity)

要更新整个数据库,可以执行以下操作:

(def student-database
  {0 {:enjoy-clojure? false, :name "jimmy",:sanity-rating 9}
   1 { :enjoy-clojure? true, :name "johnny",:sanity-rating 2}
   2 { :enjoy-clojure? true, :name "jilly",:sanity-rating 5}
   3 { :enjoy-clojure? true, :name "janey",:sanity-rating 8}
   4 {:enjoy-clojure? false, :name "jelly",:sanity-rating 10}})

(defn update-db [db]
  (zipmap (keys db)
          (map (fn [student]
                 (cond-> student
                   (:enjoy-clojure? student)
                   (assoc :sanity-rating -2)))
               (vals db))))

(update-db student-database) ;;=> 
{0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
 1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2} ...}

要更新整个数据库,可以执行以下操作:

(def student-database
  {0 {:enjoy-clojure? false, :name "jimmy",:sanity-rating 9}
   1 { :enjoy-clojure? true, :name "johnny",:sanity-rating 2}
   2 { :enjoy-clojure? true, :name "jilly",:sanity-rating 5}
   3 { :enjoy-clojure? true, :name "janey",:sanity-rating 8}
   4 {:enjoy-clojure? false, :name "jelly",:sanity-rating 10}})

(defn update-db [db]
  (zipmap (keys db)
          (map (fn [student]
                 (cond-> student
                   (:enjoy-clojure? student)
                   (assoc :sanity-rating -2)))
               (vals db))))

(update-db student-database) ;;=> 
{0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
 1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2} ...}

最简单的方法如下:

(reduce-kv (fn [acc idx row]
             (assoc acc idx
                    (if (:enjoy-clojure? row)
                      (assoc row :sanity-rating -2)
                      row)))
           {}
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
(reduce-kv (fn [res k {ec? :enjoy-clojure?}]
             (if ec?
               (assoc-in res [k :sanity-rating] -2)
               res))
           student-database
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
您也可以这样做:

(reduce-kv (fn [acc idx row]
             (assoc acc idx
                    (if (:enjoy-clojure? row)
                      (assoc row :sanity-rating -2)
                      row)))
           {}
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
(reduce-kv (fn [res k {ec? :enjoy-clojure?}]
             (if ec?
               (assoc-in res [k :sanity-rating] -2)
               res))
           student-database
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}

最简单的方法如下:

(reduce-kv (fn [acc idx row]
             (assoc acc idx
                    (if (:enjoy-clojure? row)
                      (assoc row :sanity-rating -2)
                      row)))
           {}
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
(reduce-kv (fn [res k {ec? :enjoy-clojure?}]
             (if ec?
               (assoc-in res [k :sanity-rating] -2)
               res))
           student-database
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
您也可以这样做:

(reduce-kv (fn [acc idx row]
             (assoc acc idx
                    (if (:enjoy-clojure? row)
                      (assoc row :sanity-rating -2)
                      row)))
           {}
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}
(reduce-kv (fn [res k {ec? :enjoy-clojure?}]
             (if ec?
               (assoc-in res [k :sanity-rating] -2)
               res))
           student-database
           student-database)

;;=> {0 {:enjoy-clojure? false, :name "jimmy", :sanity-rating 9}, 
;;    1 {:enjoy-clojure? true, :name "johnny", :sanity-rating -2}, 
;;    2 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2}, 
;;    3 {:enjoy-clojure? true, :name "janey", :sanity-rating -2}, 
;;    4 {:enjoy-clojure? false, :name "jelly", :sanity-rating 10}}

您在问题中没有说您希望函数只返回
(=享受clojure?true)
记录,但从您在其他答案中的注释来看,我觉得这才是您真正想要的

那么也许是这个

(defn unhinged?
  [record]
  (:enjoy-clojure? record))

(defn minus-two-students
  [student-database]
  (->> student-database
       vals
       (filter unhinged?)
       (map #(assoc % :sanity-rating -2))))
输出将是

({:enjoy-clojure? true, :name "johnny", :sanity-rating -2} 
 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2} 
 {:enjoy-clojure? true, :name "janey", :sanity-rating -2})

您在问题中没有说您希望函数只返回
(=享受clojure?true)
记录,但从您在其他答案中的注释来看,我觉得这才是您真正想要的

那么也许是这个

(defn unhinged?
  [record]
  (:enjoy-clojure? record))

(defn minus-two-students
  [student-database]
  (->> student-database
       vals
       (filter unhinged?)
       (map #(assoc % :sanity-rating -2))))
输出将是

({:enjoy-clojure? true, :name "johnny", :sanity-rating -2} 
 {:enjoy-clojure? true, :name "jilly", :sanity-rating -2} 
 {:enjoy-clojure? true, :name "janey", :sanity-rating -2})

太好了!这会打印出每个人,我可以只打印“享受clojure?真的”学生吗?当然,只需将
(map…
参数设置为
zipmap
,然后将
map
更改为
过滤器即可。谢谢!我还不太熟悉zipmap,所以我很抱歉,但是我该如何将
(map…
参数带到
zipmap
?我在做类似于
(zipmap(key db[01 2 3 4])
?我知道这不起作用,但仍在努力学习这种语言,我的意思是:(filter(fn[student](cond->student)(享受clojure?student)(assoc:sanity rating-2))(VAL学生数据库))太好了!这打印出了所有人,我能只打印出“享受clojure?真的”学生吗?当然,只要把
(map…
参数带到
zipmap
,然后将
map
更改为
过滤器
。谢谢!我对zipmap还不太熟悉,所以我很抱歉,但是我到底要如何带
(map…)
zipmap的参数
?我是否在做类似于
(zipmap(键db[0 1 2 3 4])
?我知道这不起作用,但仍在努力学习这门语言我的意思是:(filter(fn[student](cond->student)(享受clojure?student)(assoc:sanity rating-2)))(VAL学生数据库)太好了!这可以打印出每个人,有没有办法只打印出“享受clojure?真”的学生,而不打印假学生?@Student1860
(->(更新VAL学生数据库调整理智)(VAL)(筛选:享受clojure?)
那太好了!这打印出了每个人,有没有一种方法我可以只打印出“享受clojure?真”的学生,而不打印假学生?@Student1860
((->)(更新VAL学生数据库调整理智)(VAL)(筛选:享受clojure?)
啊,实际上我正在将他们的值设置为“-2”不是用它来减少它们。不过谢谢!我实际上是把它们设置为“-2”的值,不是用它来减少它们。不过谢谢!