2013-04-04 28 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