Sorting Clojure:into{}不保留排序顺序
我有一个嵌套映射,其结构类似于Clojurescript:Sorting Clojure:into{}不保留排序顺序,sorting,clojure,clojurescript,Sorting,Clojure,Clojurescript,我有一个嵌套映射,其结构类似于Clojurescript: {"6841" {"primaryTitle" "First name", "secondaryTitle" "last name"}, "7944" {"primaryTitle" "Test 2 first name", "secondaryTitle" "Test 2 last name"}} 然后,我继续使用嵌套贴图中的键对贴图进行排序,如下所示: (defn compare-title [x y] (com
{"6841"
{"primaryTitle" "First name",
"secondaryTitle" "last name"},
"7944"
{"primaryTitle" "Test 2 first name",
"secondaryTitle" "Test 2 last name"}}
然后,我继续使用嵌套贴图中的键对贴图进行排序,如下所示:
(defn compare-title [x y]
(compare [(get (second x) "primaryTitle") (get (second x) "secondaryTitle")]
[(get (second y) "primaryTitle") (get (second y) "secondaryTitle")]))
(sort compare-title @loaded-assets)
["6841"
{"primaryTitle" "First name",
"secondaryTitle" "last name"}],
["7944"
{"primaryTitle" "Test 2 first name",
"secondaryTitle" "Test 2 last name"}]}
到目前为止,排序工作正常,但由于sort函数返回如下数据结构:
(defn compare-title [x y]
(compare [(get (second x) "primaryTitle") (get (second x) "secondaryTitle")]
[(get (second y) "primaryTitle") (get (second y) "secondaryTitle")]))
(sort compare-title @loaded-assets)
["6841"
{"primaryTitle" "First name",
"secondaryTitle" "last name"}],
["7944"
{"primaryTitle" "Test 2 first name",
"secondaryTitle" "Test 2 last name"}]}
我必须使用into{}将映射转换回初始结构:
(into {} (sort compare-title my-map))
但这完全颠倒了按排序进行的排序。我尝试用以下内容替换为{}:
展平,将其转换为列表
应用行为类似于到{}的哈希映射
减少散列映射,它保留顺序,但将每个映射深深嵌套在彼此中
那么,是否可以在保留结构的同时对地图进行排序?
或者如何转换回上述原始结构,同时保留排序返回的排序结构?如前所述,地图不能按值排序。它们可以按键排序。以下是最简单的方法: 如果要按主/次标题排序,请将这两个项目放入排序键中,然后根据该键进行排序:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(def all-data {"7944" {"primaryTitle" "Test 2 first name"
"secondaryTitle" "Test 2 last name"}
"6841" {"primaryTitle" "First name"
"secondaryTitle" "last name"}})
(dotest
(let [data-keyed (forv [entry all-data]
(let [[id title-map] entry]
{:sort-key [(grab "primaryTitle" title-map)
(grab "secondaryTitle" title-map)]
:id id}))
data-sorted (vec (sort-by :sort-key data-keyed))]
(is= (spy-pretty data-keyed)
[{:sort-key ["Test 2 first name" "Test 2 last name"] :id "7944"}
{:sort-key ["First name" "last name"] :id "6841"}])
(is= (spy-pretty data-sorted)
[{:sort-key ["First name" "last name"] :id "6841"}
{:sort-key ["Test 2 first name" "Test 2 last name"] :id "7944"}])))
如前所述,地图不能按值排序。它们可以按键排序。以下是最简单的方法: 如果要按主/次标题排序,请将这两个项目放入排序键中,然后根据该键进行排序:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(def all-data {"7944" {"primaryTitle" "Test 2 first name"
"secondaryTitle" "Test 2 last name"}
"6841" {"primaryTitle" "First name"
"secondaryTitle" "last name"}})
(dotest
(let [data-keyed (forv [entry all-data]
(let [[id title-map] entry]
{:sort-key [(grab "primaryTitle" title-map)
(grab "secondaryTitle" title-map)]
:id id}))
data-sorted (vec (sort-by :sort-key data-keyed))]
(is= (spy-pretty data-keyed)
[{:sort-key ["Test 2 first name" "Test 2 last name"] :id "7944"}
{:sort-key ["First name" "last name"] :id "6841"}])
(is= (spy-pretty data-sorted)
[{:sort-key ["First name" "last name"] :id "6841"}
{:sort-key ["Test 2 first name" "Test 2 last name"] :id "7944"}])))
你可以用
使用“clojure.data.priority-map”
定义比较标题[x y]
比较[get x primaryTitle get x secondaryTitle]
[get y primaryTitle get y secondaryTitle]
通过比较标题应用优先级映射
[7944
{primaryTitle测试2名字
secondaryTitle测试2姓氏}
6841
{primaryTitle名字
secondaryTitle姓氏}]
;; => {6841{primaryTitle名字,secondaryTitle姓氏},7944{primaryTitle测试2姓氏,secondaryTitle测试2姓氏}
你可以用
使用“clojure.data.priority-map”
定义比较标题[x y]
比较[get x primaryTitle get x secondaryTitle]
[get y primaryTitle get y secondaryTitle]
通过比较标题应用优先级映射
[7944
{primaryTitle测试2名字
secondaryTitle测试2姓氏}
6841
{primaryTitle名字
secondaryTitle姓氏}]
;; => {6841{primaryTitle名字,secondaryTitle姓氏},7944{primaryTitle测试2姓氏,secondaryTitle测试2姓氏}
默认情况下,地图集合是无序的。您可以尝试按值排序,而不是按键排序,因此最好同时保留两个集合:用于查找的map和用于遍历的seq,或者查找更复杂的数据结构。对于这个问题,必须有一个规范的dupe,但我能找到的所有地图在某种程度上都有点不对劲。默认情况下,地图集合是无序的。您可以尝试使用sorted map/sorted map by,但由于您希望按值排序,而不是按键排序,因此最好同时保留这两个集合:用于查找的map和用于遍历的seq,或者查找一些更复杂的数据结构。对于这个问题,必须有一个规范的dupe,但我能找到的所有集合在某种程度上都有点不对劲。哇!我已经使用Clojure 6年了,从来都不知道优先级图!正如@leetwinski在评论中所建议的那样,我采用了为访问和遍历提供单独地图的策略。但这回答了我想问的问题。谢谢,以前从没听说过!哇!我已经使用Clojure 6年了,从来都不知道优先级图!正如@leetwinski在评论中所建议的那样,我采用了为访问和遍历提供单独地图的策略。但这回答了我想问的问题。谢谢,以前从没听说过!我很欣赏基于测试的方法,谢谢你的回答!我很欣赏基于测试的方法,谢谢你的回答!