TL;DR
update-vals
和update-keys
主要应该操作在以某些标识符为键的均质数据映射上。
https://clojure.atlassian.net/browse/CLJ-2651
https://clojure.atlassian.net/browse/CLJ-1959
但是,在核心库中没有函数可以直接从一个均质数据的序列生成这样的映射。我认为有无数的实现方式,例如
(into {} (map (juxt f identity)) coll) ; credit Sean Corfield
(persistent! (reduce #(assoc! %1 (f %2) %2) (transient {}) coll)) ; from Medley
(update-vals first (group-by f coll))
但我不知道哪个最有效。所以,我想知道在核心库中是否存在一个key-by
函数,它可以生成一个具有良好性能的映射?
Clojure 1.11引入了update-keys
和update-vals
,我和其他人开始使用它们来替代我们自己编写的map-vals
等函数。
然而,我对如何最好地创建一个可供update-keys
和update-vals
操作的映射仍不确定。通常我会从数据库中检索到一系列均质映射,如下所示
[{:id 1 :name "brandon"}
{:id 2 :name "brenda"}
{:id 3 :name "kelly"}]
然后通过(key-by :id coll)
或(index-by :id coll)
函数将其转换为
{1 {:id 1 :name "brandon"}
2 {:id 2 :name "brenda"}
3 {:id 3 :name "kelly"}}
但最好的实现方式是什么?update-vals
允许
(defn key-by
[f coll]
(update-vals first (group-by f coll)))
但这些集合通常很大,人们希望有良好的性能。在Medley中,index-by
是这样实现的
(defn index-by
[f coll]
(persistent! (reduce #(assoc! %1 (f %2) %2) (transient {}) coll)))
这看起来更有效率,这是我想不出的事情。所以我禁不住要想,当update-keys
和update-vals
被引入时,key-by
函数(这个名称听起来更好)是否成为了Clojure核心库的一个缺失的部分?