gpt4 book ai didi

Clojure sum 映射与字符串和数字

转载 作者:行者123 更新时间:2023-12-05 03:33:04 25 4
gpt4 key购买 nike

你好,我有 2 张这样的 map (可能有多张 map )

(def map1 {:a {:b 1} :c ["dog"]})
(def map2 {:a {:b 2} :c ["cat"]})

我需要将其作为返回 {:a {:b 3} :c ["dog""cat"]}

我该怎么做?

最佳答案

使用通用函数的解决方案

您可以使用通用函数——让我们在这里称它为 o+(运算符 +)——通过使用 Clojure 的多重分派(dispatch)能力。通过多次分派(dispatch),您可以避免 if - elsecond 子句 - 用于区分参数类型/类 - 从而代码保持可扩展性(可以添加更多情况而无需更改现有的代码)。 defmulti 定义末尾的函数是调度函数。在 defmethod 形式中 - 就在实际函数参数列表(向量)之前,您列出了 Clojure 在决定使用哪种方法时查看的分派(dispatch)情况。

(defmulti o+ (fn [& args] (mapv class args)))
(defmethod o+ [Number Number] [x y] (+ x y)) ;; Numbers get added
(defmethod o+ [clojure.lang.PersistentVector clojure.lang.PersistentVector]
[x y] (into (empty x) (concat x y))) ;; Vectors concatentated
(defmethod o+ [clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap]
[x y] (merge-with o+ x y)) ;; Maps merged-with #'o+ (recursive definition!)

测试

然后您可以使用(现在递归定义的)o+ 运算符融合两个映射:

(def map1 {:a {:b 1} :c ["dog"]})
(def map2 {:a {:b 2} :c ["cat"]})

(o+ map1 map2) ;; or originally: (merge-with o+ map1 map2)
;; => {:a {:b 3}, :c ["dog" "cat"]}

涵盖了更深的嵌套映射

由于此定义的递归特征 - 这也适用于嵌套更深的映射,只要它们具有相同的结构 - 并且仅使用定义的类案例(否则可以添加更多案例):

(def mapA {:a {:b 2 :c {:d 1 :e ["a"] :f 3}} :g ["b"]})
(def mapB {:a {:b 3 :c {:d 4 :e ["b" "e"] :f 5}} :g ["c"]})

(o+ mapA mapB)
;;=> {:a {:b 5, :c {:d 5, :e ["a" "b" "e"], :f 8}}, :g ["b" "c"]}

使用reduce一次添加更多 map

只要您可以在两个对象上应用o+,您就可以使用reduce 处理任意数量的映射:

(def mapA {:a {:b 2 :c {:d 1 :e ["a"] :f 3}} :g ["b"]})
(def mapB {:a {:b 3 :c {:d 4 :e ["b" "e"] :f 5}} :g ["c"]})
(def mapC {:a {:b 1 :c {:d 3 :e ["c"] :f 1}} :g ["a"]})

(reduce o+ [mapA mapB mapC]) ;; this vector could contain much more maps!
;; => {:a {:b 6, :c {:d 8, :e ["a" "b" "e" "c"], :f 9}}, :g ["b" "c" "a"]}

;; or we could define in addition:
(defmethod o+ :default [& args] (reduce o+ args))
;; which makes `o+` to a variadic function (function which can be
;; called with as many arguments you want)

;; then, whenever we add more than two arguments, it will be activated:
(o+ mapA mapB mapC)
;; => {:a {:b 6, :c {:d 8, :e ["a" "b" "e" "c"], :f 9}}, :g ["b" "c" "a"]}

;; and this also works:
(o+ 1 2 3 4 5 6)
;; => 21
(o+ ["a"] ["b" "c"] ["d"])
;; => ["a" "b" "c" "d"]

关于Clojure sum 映射与字符串和数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70383549/

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