2013-01-11 73 views
2

请看下面的代码:基本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"}) 

我希望做的是建立一个单一的列表,而不是有“色”的条目是列表中的列表。这很容易实现吗?

+0

我喜欢你的问题是如何包含了答案。 :) –

+3

@IvanKoblik更好,问题标题包含答案:) – mishadoff

+0

哈哈,我改变了标题,以便它更搜索友好:P – acron

回答

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"}) 
+0

完美,谢谢!很容易,当你知道如何! – acron

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"}) 
+0

不错。这样做有什么好处吗? (更惯用?) – acron

+0

@acron这个版本只是明确地完成这项工作,而不会使最终结果“变平”。 – mobyte