8 clojure
非常简单+愚蠢的问题:
clojure提供多张地图吗?我目前有这样的事情:
(defn wrap [func]
(fn [mp x]
(let [k (func x)]
(assoc mp k
(match (get mp k)
nil [x]
v (cons v x))))))
(defn create-mm [func lst]
(reduce (wrap func) {} lst))
Run Code Online (Sandbox Code Playgroud)
最终创建了一个地图,对于每个键,我们有一个包含该键的所有元素的向量.然而,似乎多地图是一个非常基本的数据结构,我想知道clojure是否内置了它.
谢谢
Nic*_*uer 11
我不认为这是一个独特的类型,因为Clojure的灵活性允许您通过使用地图和集合快速制作自己的.看这里:
http://paste.lisp.org/display/89840
示例代码(由Stuart Sierra提供)
(ns #^{:doc "A multimap is a map that permits multiple values for each
key. In Clojure we can represent a multimap as a map with sets as
values."}
multimap
(:use [clojure.set :only (union)]))
(defn add
"Adds key-value pairs the multimap."
([mm k v]
(assoc mm k (conj (get mm k #{}) v)))
([mm k v & kvs]
(apply add (add mm k v) kvs)))
(defn del
"Removes key-value pairs from the multimap."
([mm k v]
(let [mmv (disj (get mm k) v)]
(if (seq mmv)
(assoc mm k mmv)
(dissoc mm k))))
([mm k v & kvs]
(apply del (del mm k v) kvs)))
(defn mm-merge
"Merges the multimaps, taking the union of values."
[& mms]
(apply (partial merge-with union) mms))
(comment
(def mm (add {} :foo 1 :foo 2 :foo 3))
;; mm == {:foo #{1 2 3}}
(mm-merge mm (add {} :foo 4 :bar 2))
;;=> {:bar #{2}, :foo #{1 2 3 4}}
(del mm :foo 2)
;;=> {:foo #{1 3}}
)
Run Code Online (Sandbox Code Playgroud)
评论中指出的案件的额外测试:
(comment
(-> {} (add :a 1) (del :a 1) (contains? :a))
;;=> false
)
Run Code Online (Sandbox Code Playgroud)