我有以下数据:
[["i2" "i1"]
['("red" "blue" "green" "yellow") '("C" "D" "A" "B")]]
我想把它变成以下格式:
[["i1" "i2"]
['("A" "B" "C" "D") '("blue" "green" "red" "yellow")]]
基本上,我想:
这对我来说是一项艰巨的任务。我尝试构建类似三级步行的东西,但这不起作用。我试图使用各种地图和步行功能来惯用,但也许我只是使用" Do"并定义自定义排序图。这非常具有挑战性。
答案 0 :(得分:3)
以下是我如何处理这样的问题来提出解决方案。
(defn rearrange [[cols vals]]
首先,我注意到我尝试排序["i2" "i1"]
并重新排列以下列表。所以我只是将cols和值列表放在一起:
(let [pairs (map list cols vals)]
现在,pair是一组数据结构,如:("i2" ("red" "blue" "green" "yellow"))
。您希望函数返回一个向量。
(vector
让我们对这些对进行排序并抓住每个对中的第一项。
(mapv first (sort-by first pairs))
mapv
与(vec (map ...))
相同。 sort-by
通过比较pairs
来排序(first item)
。
如果我们用first
替换上面一行中second
的第一个实例,那么我们会按正确的顺序获取相应的值列表。但这些列表不会被排序。所以我们补充说:
(mapv (comp sort second) (sort-by first pairs)))))
最终结果:
(defn rearrange [[cols vals]]
(let [pairs (map list cols vals)]
(vector
(mapv first (sort-by first pairs))
(mapv (comp sort second) (sort-by first pairs)))))
这不是你能写的最好的功能版本,但是一半的战斗正在到达这一点。如果你了解它是如何工作的,你可以开始改进它。
(def data [["i3" "i1" "i2"]
['("a" "c" "d" "b")
'("elephant" "zebra" "tiger" "cat")
'("red" "yellow" "blue" "green")]])
user=>(rearrange data)
[["i1" "i2" "i3"]
[("cat" "elephant" "tiger" "zebra")
("blue" "green" "red" "yellow")
("a" "b" "c" "d")]]
答案 1 :(得分:2)
(def data [["i2" "i1"] ['("red" "blue" "green" "yellow") '("C" "D" "A" "B")]])
(defn transpose [m] (apply mapv vector m))
(defn arrange [[x y]] (->> [x (map sort y)] transpose (sort-by first) transpose))
(arrange data)
;=> [["i1" "i2"] [("A" "B" "C" "D") ("blue" "green" "red" "yellow")]]
答案 2 :(得分:1)
你正在寻找replace fn:
(defn my-sort [[cols vals]]
(let [ vals-sorted (map sort vals)
cols-sorted (sort cols)
cols->sorted-vals (zipmap cols vals-sorted)]
[cols-sorted
(replace cols->sorted-vals cols-sorted)]))