我试图将一个字符串分成n个可变大小的块。
作为输入,我有一个不同块大小的seq:
(10 6 12)
还有一个字符串:
"firstchunksecondthirdandlast"
我想用大小分割字符串:
("firstchunk" "second" "thirdandlast")
作为一个新手,我仍然很难绕过最惯用的方式来做这件事。
答案 0 :(得分:2)
以下是两种方法:
一个版本使用reduce
,如果您想要携带某种状态(此处:您当前所处的索引),您可以经常使用second
。 reduce需要应用;; 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]))
fn调用才能在表单中显示结果。
(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])))))
另一个版本首先构建了start-end的索引,然后使用destruct将它们从序列中删除:
LocationSettingsRequest.Builder
请注意,如果字符串太短,这些都不是健壮的并且会丢失丑陋的错误。所以你应该更加防守并使用一些断言。
答案 1 :(得分: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"]