2016-07-03 9 views
0

可変サイズのn個のチャンクに分割しようとしています。入力としてストリングを別のサイズのチャンクに分割する

私は別のチャンクの大きさの配列を持っている:

(10 6 12) 

と文字列:

"firstchunksecondthirdandlast" 

私はそうとサイズを使用して文字列を分割したいと思います:

("firstchunk" "second" "thirdandlast") 

初心者でも、私はまだこれを行うために最も慣用的な方法の周りに私の頭を包んで苦労している。ここで

答えて

1

はこれを行うには、2つの方法である:

1つのバージョンは、あなたが(:現在の位置だインデックスこちら)状態のいくつかの種類を運ぶためにしたい場合は、非常に頻繁に使用することができますreduceを使用しています。 reduceにはフォームに結果を持たせるためにsecond fnコールが適用されている必要があります。

;; Simply take second as a result: 
(let [s "firstchunksecondthirdandlast"] 
    (reduce 
    (fn [[s xs] len] 
     [(subs s len) 
     (conj xs (subs s 0 len))]) 
    [s []] 
    [10 6 12])) 

他のバージョンでは、最初のスタート・エンドのインデックスを構築して、シーケンスからそれらを取得するために消滅を使用しています。これらのいずれも堅牢であることを

(let [s "firstchunksecondthirdandlast"] 
    (mapv 
    (fn [[start end]] 
     (subs s start end)) 
    ;; Build up the start-end indices: 
    (partition 2 1 (reductions + (cons 0 [10 6 12]))))) 

注意をしている場合醜いエラーを投げます文字列が短すぎます。だからあなたははるかに防御的で、いくつかの主張を使うべきです。

+0

この2つのソリューションはありがとうございます。 私は実際には気が気にならない、純粋なJavaでやっていたこととはまったく違う – joel

0

これは私の問題です(まだ言語の初心者です)、チャンクリストが空になるまで無名関数と再帰を使用します。このパターンは、条件が満たされるまで結果を蓄積したい場合に便利です。

str-orig chunks-orig []は、完全な文字列、チャンクの完全なリスト、および結果を収集するための空のvecを設定します。

(defn split-chunks [str-orig chunks-orig] 
    ((fn [str chunks result] 
    (if-let [len (first chunks)] (recur 
            (subs str len) 
            (rest chunks) 
            (conj result (subs str 0 len))) 
     result)) 
    str-orig chunks-orig [])) 

(split-chunks "firstchunksecondthirdandlast" '(10 6 12)) 
; ["firstchunk" "second" "thirdandlast"] 
関連する問題