关于序列转换的clojure惯用语问题

5

我正在学习Clojure,遇到了一个问题,需要你给予指导。

我有一系列事件。每个事件都包括一个“日期”。

(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"]])

我希望将此转换为“延迟时间轴”,即每年包含一个向量的序列。从第一个事件的年份开始,一直持续到无限大。
[[[:marry "Catherine of Aragon"]] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [[:unmarry "Catherine of Aragon"]] [] [] [] [] [] [[:marry "Ane Boleyn"]] [] [] [[:unmarry "Anne Boleyn"] [:marry "Jayne Seymour"]] ...]

我会考虑重新排版以符合Lisp/Clojure约定,将尾括号放在一行上,参见:http://techbehindtech.com/2010/12/09/clojure-good-coding-guidelines/。 - 0x89
2个回答

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))))))

快速测试:

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

3
我建议使用类似以下的语句:

我会建议使用类似以下的语句:

(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))))))

测试:

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

我假设事件列表也是无限的 :)
更新后进行了改进,借鉴了cgrand的一些想法(谢谢)

谢谢。当同一日期有多个事件时,它会出现错误,即[1515:c] [1515:d]。然而,其中有很多好的指针,也许我可以自己解决其余的问题。 - GHZ
@GHZ 啊,没看到那个。不过cgrand的更好 :) 重构后作为第二个选项。 - j-g-faustus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接