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核心中缺失的一环?