要分割的序列是 a splittee
,分割点(aka. splitter
)的元素标记了分割的最后一个元素。
从你的例子:
分裂者:[1 2 3 4 5 6]
分离器:[3 5]
结果:((1 2 3)(4 5)(6))
因为得到的分区总是一个递增的整数序列,并且递增的整数序列x
可以定义为start <= x < end
,所以拆分器元素可以end
根据定义转换为一个序列。
所以,从[3 5]
,我们想找到以4
和结尾的子序列6
。
然后通过添加start
,splitter
可以转换为 的序列[start end]
。start
也end
使用了分流器的 and 。
所以,分离器[3 5]
就变成了:
[[1 4] [4 6] [6 7]]
拆分器转换可以这样完成
(->> (concat [(first splittee)]
(mapcat (juxt inc inc) splitter)
[(inc (last splittee))])
(partition 2)
splitter
转换后的结果和期望的结果之间有很好的对称性。
[[1 4] [4 6] [6 7]]
((1 2 3) (4 5) (6))
那么问题就变成了如何提取splittee
由[start end]
内部转换拆分器划分的子序列
clojure 具有subseq
可用于在有序序列按start
和end
标准中查找子序列的功能。我可以为transformed-splitter的每个元素映射splittee的子序列
(map (fn [[x y]]
(subseq (apply sorted-set splittee) <= x < y))
transformed-splitter)
通过结合上述步骤,我的答案是:
(defn partition-by-seq
[splitter splittee]
(->> (concat [(first splittee)]
(mapcat (juxt inc inc) splitter)
[(inc (last splittee))])
(partition 2)
(map (fn [[x y]]
(subseq (apply sorted-set splittee) <= x < y)))))