2011-01-31 21 views
5

Clojure'ı öğreniyorum ve geldiğim bu problemle doğru yönde bir itme ihtiyacım var.Sekans transformasyonu üzerine deyimsel klojure soru

Bir dizi olayım var. Her olay bir 'tarih' içerir.

(def events 
    [ 
    [1509 :marry "Catherine of Aragon"] 
    [1527 :unmarry "Catherine of Aragon"] 
    [1533 :marry "Anne Boleyn"] 
    [1536 :unmarry "Anne Boleyn"] 
    [1536 :marry "Jane Seymour"] 
    [1537 :unmarry "Jane Seymour"] 
    [1540 :marry "Anne of Cleves"] 
    [1540 :unmarry "Anne of Cleves"] 
    [1540 :marry "Catherine Howard"] 
    [1542 :unmarry "Catherine Howard"] 
    [1543 :marry "Catherine Parr"]]) 

I, yani yılda bir vektörü içeren bir dizi, bir yapay zaman çizgisine Bu dönüştürme için. İlk etkinliğin yılı ile başlayan ve sonsuza kadar devam eden.

[[[:marry "Catherine of Aragon"]] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [[:unmarry "Catherine of Aragon"]] [] [] [] [] [] [[:marry "Ane Boleyn"]] [] [] [[:unmarry "Anne Boleyn"] [:marry "Jayne Seymour"]] ...] 
+0

Ben sondaki koyma/Clojure kuralını peltek uymaları yeniden biçimlendirme dikkate alacağını bir satırda parens, bkz: http://techbehindtech.com/2010/12/09/clojure-iyi kodlama yönergeleri/ – 0x89

cevap

8
(def timeline 
    (let [events-by-year (group-by first events)] 
    (map #(map next (events-by-year %)) 
     (iterate inc (reduce min (keys events-by-year)))))) 

Hızlı testi:

=> (take 30 timeline) 
(((:marry "Catherine of Aragon"))()()()()()()()()()()()()()()()() 
() ((:unmarry "Catherine of Aragon"))()()()()() ((:marry "Anne Boleyn"))() 
() ((:unmarry "Anne Boleyn") (:marry "Jane Seymour")) ((:unmarry "Jane Seymour")) 
()) 
3

ben gibi bir şey öneririm:

(defn timeline 
    ([] (timeline (ffirst *events*) *events*)) 
    ([time evts] 
    (let [[now later] (split-with #(= time (first %)) evts)] 
     (cons (map rest now) 
      (lazy-seq (timeline (inc time) later)))))) 

Testi:

user> (take 30 (timeline)) 
(((:marry "Catherine of Aragon"))()()()()()()()()()()()()()()()()() 
((:unmarry "Catherine of Aragon"))()()()()() ((:marry "Anne Boleyn"))()() 
((:unmarry "Anne Boleyn") (:marry "Jane Seymour")) ((:unmarry "Jane Seymour"))()) 

Ben olayların listesini de :)

Güncelleme sonsuz olduğunu varsayarak yaşıyorum iyileştirmelerle ve cgrand'dan birkaç fikir ödünç aldınız (teşekkürler :)

+0

Teşekkürler. Aynı tarihte birden fazla olay olduğunda, yani [1515: c] [1515: d]. Ancak, orada birçok iyi işaretçi var, belki de geri kalanını kendim bulabilirim. – GHZ

+0

@GHZ Ah, bunu kaçırdı. Eh, cgrand 'neyse daha güzeldi :) Refactored, ikinci bir seçenek olarak bırakarak. –

İlgili konular