2011-08-26 25 views
8

BuGRUP TARAFINDAN ve Toplama Clojure

(def a [{:firmAccount "MSFT" :Val 10 :PE 3 } 
{:firmAccount "MSFT" :Val 15 :PE 4} 
{:firmAccount "GOG" :Val 15 :PE 3} 
{:firmAccount "YAH" :Val 8 :PE 1}]) 

benziyor verileri I tarafından gruplandırmak istediğiniz var

[{:firmAccount "MSFT" :Val 25 :PE 7} 
    {:firmAccount "GOG" :Val 15 :PE 3}  
    {:FirmAccount "YAH" :Val 8 :PE 1}] 

gibi bir şey gerçekten önemsiz bir şeydir ve SQL ben bile iki kez düşünmek olmaz ama Clojure öğreniyorum beri bana lütfen ayı

cevap

8

Clojure.core işleviyle grup-yerleşik bir sahiptir. Çözüm, haritalarda hem metnin hem de int değerinin varlığıyla biraz çirkinleşir. Ona, burada kabataslak eklenti işlevini kullanırsanız

(map (fn [[firmAccount vals]] 
    {:firmAccount firmAccount 
    :Val (reduce + (map :Val vals)) 
    :PE (reduce + (map :PE vals))}) 
    (group-by :firmAccount a)) 
+1

Çok teşekkürler. Benim için iyi çalışıyor ve çok özlü. Ayrıca cevap, assoc'u nasıl kullanacağımı, birleştirmeyi, uygulayacağınızı, disoste edebileceğimizi, grup-harita ve haritanın nasıl harika olduğunun tek bir örnekte olduğunun farkındadır. – Ash

1

ile haritaların yeni bir harita dizisi veya haritayı oluşturmayı deneyin aynı yapısı. Bu yeni haritaya elemanlar eklemek için bir işlev yazabilirsiniz, bu ise: eğer firma hesabı varsa o alanları toplar. Belki böyle bir harita var mı? gibi kişiselleştirilmiş bir eklenti fonksiyonu ile

(def a {"MSFT" {:Val 25 :PE 7 } 
    "GOG" {:Val 15 :PE 3} 
    "YAH" {:Val 8 :PE 1}}) 

:

(add-to-map [element map] 
    (if (contains? (find-name element)) 
    {map (add-fields element (find (find-name element)))} 
    {map element})) 
+0

Eh, yapısını değiştirmek gerekmez:

(for [m (group-by :firmAccount a)] (assoc (apply merge-with + (map #(dissoc % :firmAccount) (val m))) :firmAccount (key m))) 

+0

Buradaki veri yapısı nedeniyle değişiklik gerekli. Cevabınızda kullandığınız yapı, istenen giriş değil, istenen cevaptır. – mac

5

Ve şeyiyle

Buradaki harita kullanan alternatif bir versiyonu. Bu fikirleri nasıl kullanırsınız?
+0

İlginç, bir. Çok teşekkürler – Ash