我正在尝试按键值对一个映射进行排序。给定这个映射:
{:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20}}
我想按照排名
的值排序:
{:2 {:bar "other" :rank 20} :1 {:bar "something" :rank 10} }
是否可以使用 sort-by
进行排序?
提前感谢您的帮助。
我正在尝试按键值对一个映射进行排序。给定这个映射:
{:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20}}
我想按照排名
的值排序:
{:2 {:bar "other" :rank 20} :1 {:bar "something" :rank 10} }
是否可以使用 sort-by
进行排序?
提前感谢您的帮助。
优先级映射与排序映射非常相似,但排序映射会按键产生一个已排序条目序列,而优先级映射则按值产生已排序的条目序列。
; You'll need to add [org.clojure/data.priority-map "0.0.7"] to :dependencies first
user=> (require '[clojure.data.priority-map :as pm])
; nil
user=> (pm/priority-map-keyfn-by :rank >
:1 {:bar "something" :rank 10}
:2 {:bar "other" :rank 20})
; {:2 {:rank 20, :bar "other"}, :1 {:rank 10, :bar "something"}}
使用 sort-by
很容易实现,但是由于它按升序排序,因此您需要使用 reverse
来使其以正确的方式进行。
(reverse
(sort-by (comp :rank second)
{:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20}}))
sort-by除了可选的自定义比较器外,还需要一个键函数
; keyfn comparator
(sort-by (comp :rank second) >
{:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20}})
;=> ([:2 {:bar "other", :rank 20}] [:1 {:bar "something", :rank 10}])
(get)
而不是:rank
来完成这个任务?例如,一个字符串是键名。 - triplejfn
的地方使用了:rank
,因此可以使用任何fn
:例如(comp #(get % "foo") second)
- 关键字可以使用与sort-by
无关,而与Maps
的工作方式有关,即(:foo a-map)
可以工作,但("foo" a-map)
不能。 -(为了完整起见, Maps
是对它们自身的查找,因此(a-map :foo)
也可以工作) - birdspider另请参见此答案
升序:
user=> (sort-by (comp :rank second) < {:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20} :3 {:bar "bar" :rank 15}})
([:1 {:bar "something", :rank 10}] [:3 {:bar "bar", :rank 15}] [:2 {:bar "other", :rank 20}])
降序:
user=> (sort-by (comp :rank second) > {:1 {:bar "something" :rank 10} :2 {:bar "other" :rank 20} :3 {:bar "bar" :rank 15}})
([:2 {:bar "other", :rank 20}] [:3 {:bar "bar", :rank 15}] [:1 {:bar "something", :rank 10}])
(into {} ...)
进行包装。