在clojure中惰性地合并(分组)巨大序列

在clojure中惰性地合并(分组)巨大序列,clojure,merge,data-conversion,lazy-sequences,Clojure,Merge,Data Conversion,Lazy Sequences,例如: 我们有两个通过读取csv创建的时间序列惰性地图序列。这个 两个延迟序列从不同的日期开始: 确切地说,类型:date不是字符串,而是由clj time强制的Jodatime 和:日期为每个序列排序 第一种选择是使用groupby函数,但我想这不能创建lazy seq。我相信分组需要热切的评价 第二种选择是使用按函数划分,但我无法将其应用于我的输入,因为我缺乏闭包技巧 输入序列非常庞大(每个序列约1GB),我想一次计算多个(约100个)序列。 因此,我希望延迟计算可以避免Outofmemo

例如:

我们有两个通过读取csv创建的时间序列惰性地图序列。这个 两个延迟序列从不同的日期开始:


确切地说,类型:date不是字符串,而是由clj time强制的Jodatime 和:日期为每个序列排序

第一种选择是使用groupby函数,但我想这不能创建lazy seq。我相信分组需要热切的评价

第二种选择是使用按函数划分,但我无法将其应用于我的输入,因为我缺乏闭包技巧

输入序列非常庞大(每个序列约1GB),我想一次计算多个(约100个)序列。
因此,我希望延迟计算可以避免Outofmemory错误。

如果您的项目按日期排序,您可以轻松地对它们进行延迟合并(如合并排序算法):

然后,您可以按日期对生成的惰性序列进行分区(这也会生成惰性序列):

因此,接下来要做的就是使用
map


如果您有更多的输入序列,您可以使用相同的策略,只需使用变量args重写
merge lazy
(或使用
merge lazy
(reduce merge lazy sequences)
这也会生成序列的惰性序列合并)

您的输入序列是按日期排序的吗?
INPUT
 lazy-seq1
  ({:date "20110515" :val1 123}
   {:date "20110516" :val1 143}
   {:date "20110517" :val1 1153} ...)
 lazy-seq2
  ({:date "20110517" :val2 151}
   {:date "20110518" :val2 1330} ...)
EXPECTED OUTPUT
 lazy-seq3 
  ({:date "20110515" :vals {:val1 123}}
   {:date "20110516" :vals {:val1 143}}
   {:date "20110517" :vals {:val1 1153 :val2 151}}
   {:date "20110518" :vals {:val1 ... :val2 1330}}
  ...))
(defn merge-lazy [seq1 seq2]
  (cond (empty? seq1) seq2
        (empty? seq2) seq1
        (< (Integer/parseInt (:date (first seq1)))
           (Integer/parseInt (:date (first seq2)))) (cons (first seq1)
                                                      (lazy-seq (merge-lazy (rest seq1) seq2)))
        :else (cons (first seq2) (lazy-seq (merge-lazy seq1 (rest seq2))))))
user> (def seq1
        '({:date "20110515" :val1 123}
          {:date "20110516" :val1 143}
          {:date "20110517" :val1 1153}))
#'user/seq1
user> (def seq2 '({:date "20110517" :val2 151}
                  {:date "20110518" :val2 1330}))

user> (merge-lazy seq1 seq2)
({:date "20110515", :val1 123} {:date "20110516", :val1 143} 
 {:date "20110517", :val2 151} {:date "20110517", :val1 1153} 
 {:date "20110518", :val2 1330})
user> (partition-by :date (merge-lazy seq1 seq2))
(({:date "20110515", :val1 123}) 
 ({:date "20110516", :val1 143}) 
 ({:date "20110517", :val2 151} {:date "20110517", :val1 1153})
 ({:date "20110518", :val2 1330}))