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
时,如果在 Clojure 核心中没有引入key-by
(这个名字对我来说更好)作为缺失的部件?