在 clojure 中,我想从一个大的惰性序列(可能是一个无限序列)中计算几个子向量。 最简单的方法是将惰性序列转换为向量,然后计算子向量。但当我这么做的时候,我就失去了懒惰。
我有一个大序列big-sequence
和positions
,即开始和结束位置的列表。我想做以下计算,但是懒惰:
(let [positions '((5 7) (8 12) (18 27) (28 37) (44 47))
big-sequence-in-vec (vec big-sequence)]
(map #(subvec big-sequence-in-vec (first %) (second %)) positions))
; ([5 6] [8 9 10 11] [18 19 20 21 22 23 24 25 26] [28 29 30 31 32 33 34 35 36] [44 45 46])
可行吗?
备注:如果big-sequence
是无限的,vec
将永远不会返回!
最佳答案
您正在要求一个惰性序列的子向量的惰性序列。我们可以如下逐层开发。
(defn sub-vectors [spans c]
(let [starts (map first spans) ; the start sequence of the spans
finishes (map second spans) ; the finish sequence of the spans
drops (map - starts (cons 0 starts)) ; the incremental numbers to drop
takes (map - finishes starts) ; the numbers to take
tails (next (reductions (fn [s n] (drop n s)) c drops)) ; the sub-sequences from which the sub-vectors will be taken from the front of
slices (map (comp vec take) takes tails)] ; the sub-vectors
slices))
例如,给定
(def positions '((5 7) (8 12) (18 27) (28 37) (44 47)))
我们有
(sub-vectors positions (range))
; ([5 6] [8 9 10 11] [18 19 20 21 22 23 24 25 26] [28 29 30 31 32 33 34 35 36] [44 45 46])
跨度和基本序列都被延迟处理。两者都可以是无限的。
例如,
(take 10 (sub-vectors (partition 2 (range)) (range)))
; ([0] [2] [4] [6] [8] [10] [12] [14] [16] [18])
关于clojure - 在 clojure 中,如何从一个大的惰性序列中惰性地计算多个子序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24230109/