如何对一组clojure地图进行排序?

Zub*_*air 17 clojure

我有一组这样的地图:

#{
  {:name "a" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "c" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
}
Run Code Online (Sandbox Code Playgroud)

:我想要一个有序列表,就像sql order-by name:

[
  {:name "a" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "a" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "b" :value "b" ... more stuff here}
  {:name "c" :value "b" ... more stuff here}
]
Run Code Online (Sandbox Code Playgroud)

: 我怎样才能做到这一点?

Leo*_*nel 31

函数sort-by是你正在寻找的:

(def s
  #{
    {:name "d" :value "b" }
    {:name "b" :value "b" }
    {:name "c" :value "b" }
    })
(sort-by :name s)
Run Code Online (Sandbox Code Playgroud)


Art*_*ldt 7

sort-by是一个很好的答案,并且在它工作的简单情况下使代码更好.此外,排序功能可以采用一种功能从每个地图中提取同伴密钥,因为您需要对每个项目进行一些处理.在这个例子中,我使用一个sort函数来提取每个名称,然后对它们进行字符串比较.

(sort #(compare (:name %1) (:name %2)) data)
=>  ({:name "a", :value "b"} {:name "b", :value "b"} {:name "c", :value "b"})
Run Code Online (Sandbox Code Playgroud)

如果您的集合具有不同的名称,则这非常有用:

(sort #(compare (:value %1) (:name %2)) data)
=> ({:name "a", :value "b"} {:name "c", :value "b"} {:name "b", :value "b"})
Run Code Online (Sandbox Code Playgroud)

compare函数是java的.compareto()的更好版本,因为它正确处理nil并正确地比较了clojure集合.基本上是使用的捷径.在大多数情况下,操作者

(sort #(. (:name %1) (compareTo (:name %2))) data)
=> ({:name "a", :value "b"} {:name "b", :value "b"} {:name "c", :value "b"})
Run Code Online (Sandbox Code Playgroud)


May*_*iel 5

(def set-of-maps #{{:name "d"}, {:name "b"}, {:name "a"}})

- > clojure.core/sort-by

(sort-by :name set-of-maps)

; => ({:name "a", :value "b"} {:name "c", :value "b"} {:name "d", :value "b"})