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