2013-04-04 47 views
2

我有一個數據結構,看起來類同Clojure的地圖捲起

[{:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 111} 
{:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 222} 
{:Gender "Girl" :Cat1 "Foo" :Cat2 "Bar" :SKU 333} 
{:Gender "Boy" :Cat1 "Foo" :Cat2 "Woo" :SKU 444}] 

林想打造出一個數據結構,看起來像

[{:Name "Boy" 
     :Children 
     { :Name "Foo" 
     :Children 
      {:Name "Bar" 
      :Children 
      {:SKU 111} 
      {:SKU 222} 
      } 
      {:Name "Woo" 
      :Children 
      {:SKU 444} 
      } 
     } 
    {:Name "Girl" 
     :Children 
     {:Name "Foo" 
     :Children 
     {:Name "Bar" 
      :Children 
      {:SKU 333} 
     } 
     }    
     }]   

林相當新的Clojure所以如果答案請原諒我。

+0

因爲地圖沒有定義的順序,使用一組列表而不是地圖列表是否可以接受? – 2013-04-04 18:12:21

+0

或名稱:cat1:cat2固定可靠嗎? – 2013-04-04 18:18:14

+0

@ArthurUlfeldt這些名字固定而且可靠。 – Bryce 2013-04-04 19:45:25

回答

0

下面是解決方案(注::Children應該是地圖列表)

(def data [{:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 111} 
      {:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 222} 
      {:Gender "Girl" :Cat1 "Foo" :Cat2 "Bar" :SKU 333} 
      {:Gender "Boy" :Cat1 "Foo" :Cat2 "Woo" :SKU 444}]) 


(defn gp-by [data key] 
    (->> (group-by key data) 
     (map (fn [[k v]] {:Name k 
         :Children (map #(dissoc % key) v)})))) 


(map (fn [m] (assoc m :Children 
        (map (fn [n] (assoc n :Children (gp-by (n :Children) :Cat2))) 
         (gp-by (m :Children) :Cat1)))) (gp-by data :Gender)) 
+0

精美的作品。感謝您的迴應。 – Bryce 2013-04-05 15:32:12

0

不正是你想要的,但也許接近:

user=> (def foo [{:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 111} 
    #_=>  {:Gender "Boy" :Cat1 "Foo" :Cat2 "Bar" :SKU 222} 
    #_=>  {:Gender "Girl" :Cat1 "Foo" :Cat2 "Bar" :SKU 333} 
    #_=>  {:Gender "Boy" :Cat1 "Foo" :Cat2 "Woo" :SKU 444}]) 
#'user/foo 

user=> (group-by (juxt :Gender :Cat1 :Cat2) foo) 
    {["Boy" "Foo" "Bar"] [{:Gender "Boy", :Cat2 "Bar", :Cat1 "Foo", :SKU 111} 
    {:Gender "Boy", :Cat2 "Bar", :Cat1 "Foo", :SKU 222}], 
    ["Girl" "Foo" "Bar"] [{:Gender "Girl", :Cat2 "Bar", :Cat1 "Foo", :SKU 333}], 
    ["Boy" "Foo" "Woo"] [{:Gender "Boy", :Cat2 "Woo", :Cat1 "Foo", :SKU 444}]} 

user=> (def foo2 (group-by (juxt :Gender :Cat1 :Cat2) foo)) 
#'user/foo2 

user=> (zipmap (keys foo2) (map #(map :SKU %) (vals foo2))) 
{["Boy" "Foo" "Woo"] (444), ["Girl" "Foo" "Bar"] (333), ["Boy" "Foo" "Bar"] (111 222)} 
+0

我設法通過上面使用的組,但從未想過之後的zipmap。最後,我需要使用cheshire生成一個json字符串來創建一個數據文件。生病嘗試這個新的信息,讓你知道。 – Bryce 2013-04-04 19:20:29