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核心库中缺失的一环?(这个名字听起来更好)?