基本Clojure:如何展平嵌套列表?

时间:2013-01-11 08:31:20

标签: clojure

请查看以下代码:

(def data {:color ["R", "B", "G"] :name "Hello" :up "down"})

(defn collapse-vector-kvp [k v] 
   (map #(hash-map k %) v))

(defn collapse-map [m]
   (map #(let 
      [x %] 
      (if (vector? (val x)) 
            (collapse-vector-kvp (key x) (val x))
            (hash-map (key x) (val x))
        )) m))

(collapse-map data)

=> ({:name "Hello"} ({:color "R"} {:color "B"} {:color "G"}) {:up "down"})

我想要做的是创建一个列表,而不是让'color'条目位于列表中的列表中。这容易实现吗?

2 个答案:

答案 0 :(得分:6)

user=> (def data2 '({:name "Hello"} ({:color "R"} {:color "B"} {:color "G"}) {:up "down"}))
#'user/data2
user=> (flatten data2)
({:name "Hello"} {:color "R"} {:color "B"} {:color "G"} {:up "down"})

答案 1 :(得分:2)

collapse-map的另一个版本:

(defn collapse-map [m]
  (let [sep-m (group-by (comp vector? val) m)]
    (concat (map (fn [[k v]] {k v}) 
                 (sep-m false))
            (apply concat (map (fn [[k v]] 
                                 (collapse-vector-kvp k v)) 
                               (sep-m true))))))

(def test-data {:color ["R" "B" "G"] 
                :name "Hello" 
                :k ["v1" "v2" "v3"] 
                :up "down"})

(collapse-map test-data)
=> ({:name "Hello"}
    {:up "down"}
    {:color "R"}
    {:color "B"}
    {:color "G"}
    {:k "v1"}
    {:k "v2"}
    {:k "v3"})