在向量向量内排序列表

时间:2014-04-03 15:40:29

标签: list sorting vector clojure

我有以下数据:

[["i2" "i1"]
 ['("red" "blue" "green" "yellow") '("C" "D" "A" "B")]]

我想把它变成以下格式:

[["i1" "i2"]
 ['("A" "B" "C" "D") '("blue" "green" "red" "yellow")]]

基本上,我想:

  1. 按字母顺序对每个列表排序
  2. 按字母顺序对第一个内部矢量进行排序
  3. 排序重新排列第二个内部矢量,使其具有与第一个内部矢量相同的新顺序
  4. 这对我来说是一项艰巨的任务。我尝试构建类似三级步行的东西,但这不起作用。我试图使用各种地图和步行功能来惯用,但也许我只是使用" Do"并定义自定义排序图。这非常具有挑战性。

3 个答案:

答案 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)]))