2016-06-16 7 views
0

例:マージ(グループ別)巨大なシーケンスなまけ

私たちは、csvファイルを読み込むことによって作成したマップの2時系列怠惰な配列を有します。 2レイジーシーケンスが異なる日に開始します。


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

正確には、の種類:日付は文字列ではなく、JodatimeはCLJ-時間 とによって強要:日付は、各シーケンスのためにソートされます。

最初の選択肢はグループバイ関数を使用しますが、これはlazy-seqを作成できないと思います。私はグループバイが熱心な評価を必要としていると信じています。

2番目の選択肢はパーティションバイ機能を使用しますが、クロージャのスキルが不足しているため、これを自分の入力に適用できません。

入力seqは非常に大きく(シーケンスあたり1GBまで)、一度に多くの(〜100)シーケンスを計算したいと思います。 したがって、Outfmemoryエラーを回避するために遅延評価が必要です。

+0

あなたの入力シーケンスは日付で区切られていますか? – leetwinski

答えて

2

あなたの項目が日付順にソートされている場合、あなたは簡単に(マージソートのアルゴリズムのように)それらの怠惰なマージを行うことができます。

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

あなたが行うので、次の事、ちょうどあなたが複数の入力シーケンスを持っている場合、あなただけのmerge-lazyで変数引数(または単にreducemerge-lazyを書き換え、同じ戦略を使用することができますmap

を持つすべてのグループを処理している:(reduce merge-lazy sequences)これも希望シーケンスの怠惰なシーケンスを生成する 'merge)