clojure - 在 clojure 中,如何从一个大的惰性序列中惰性地计算多个子序列?

标签 clojure lazy-evaluation

在 clojure 中,我想从一个大的惰性序列(可能是一个无限序列)中计算几个子向量。 最简单的方法是将惰性序列转换为向量,然后计算子向量。但当我这么做的时候,我就失去了懒惰。

我有一个大序列big-sequencepositions,即开始和结束位置的列表。我想做以下计算,但是懒惰:

(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/

相关文章:

haskell - 防止 "getCurrentDirectory: resource exhausted (Too many open files)"错误

clojure - 用于引导 repl 的引用 clojure

clojure - 在 Clojure 中从字符串创建列表

vector - Clojure - 合并两个不同大小向量的向量

lazy-evaluation - idris 真的是 "strictly evaluated?"

python - 从 C++ 调用 Python 或 Lua 来计算表达式,仅在需要时计算未知变量

clojure - CounterClockWise 中的代码完成?

struct - Clojure 结构嵌套在另一个结构中

c# - 来自给定有限列表的linq无限列表

functional-programming - 使用 Lazy.jl 在 Julia 中生成惰性范围