2013-03-05 11 views
9

整数の代わりに整数のseqに基づいてseqを分割するのはもっと慣用的な方法でしょうか?ここで整数のseqによる分割

は私の実装です:次に

(defn partition-by-seq 
    "Return a lazy sequence of lists with a variable number of items each 
    determined by the n in ncoll. Extra values in coll are dropped." 
    [ncoll coll] 
    (let [partition-coll (mapcat #(repeat % %) ncoll)] 
    (->> coll 
     (map vector partition-coll) 
     (partition-by first) 
     (map (partial map last))))) 

(partition-by-seq [2 3 6] (range))((0 1) (2 3 4) (5 6 7 8 9 10))を生み出します。

答えて

3

マイナー怠惰の追加とwhen-let代わりにempty?の明示的なテストではAnkurの答えのバリエーション、。

(defn partition-by-seq [parts coll] 
    (lazy-seq 
     (when-let [s (seq parts)] 
     (cons 
      (take (first s) coll) 
      (partition-by-seq (rest s) (nthrest coll (first s))))))) 
+0

(cons x nil)がちょうど(x)なので、ここで 'when-let'を使うのが好きで、ifバージョンよりはるかにクリーンです。なぜ 'drop'の代わりに' nthrest'を使うのですか?内側の部分は、 '' @(最初の部分)(cons(take n coll)(分割部分)(drop n coll))))))) ' – ToBeReplaced

+0

@ToBeReplaced' nthrestはちょうど落ち込んで、熱心に落ちるもので、私はこの文脈では適切だと思った。二番目の考えでは、私は全く問題があるかどうかは分かりません。実際、「最初の」は「時」の中に移動することができます。 –

2
(first (reduce (fn [[r l] n] 
       [(conj r (take n l)) (drop n l)]) 
       [[] (range)] 
       [2 3 6])) 

=> [(0 1) (2 3 4) (5 6 7 8 9 10)] 
+0

'reduce'は怠け者 – Ankur

+0

男ではありません...減らす(取る'でも、最初のように、これは、cons' ''外レイジーseq'を取るこ​​とによっても、lazier作ることができるすべてのもの... – ToBeReplaced

4

あなたの実装では正常に見えるが、あなたの場合のようにマップし、既存のパーティションごとに使用するよりもlazy-seqに包まれた、単純な再帰を使用しています(そして、より効率的であることが判明)もっと簡単な解決策があるかもしれません。

(defn partition-by-seq [ncoll coll] 
    (if (empty? ncoll) 
    '() 
    (let [n (first ncoll)] 
     (cons (take n coll) 
      (lazy-seq (partition-by-seq (rest ncoll) (drop n coll))))))) 
+1

を行いますn coll)は熱心に評価されていません。 –

関連する問題