通过访问其先前元素来处理seq

时间:2012-06-20 01:42:09

标签: clojure

我想创建一个序列,但要创建它需要访问前两个元素的每个元素。在clojure中做这些事情的一般方法是什么?

所以两个略有不同的案例 - a)seq是(a b c)当我处理c时我想要访问a和b .... b)具有通过始终能够访问前两个元素来创建序列本身的能力。

谢谢, 穆尔塔扎

3 个答案:

答案 0 :(得分:3)

分区几乎免费为您提供:

(partition-all 3 1 (range 100))
((0 1 2) (1 2 3) (2 3 4) (3 4 5) (4 5 6) (5 6 7) (6 7 8) ... )

然后你可以在分区序列上映射你的函数:

(map my-func (partition-all 3 1 (range 100)))

如果你的seq不是三的倍数,你只需要让你的函数知道最后一个段可能少于三个元素的事实。如果您想删除任何额外内容,请使用partition代替partition-all

答案 1 :(得分:2)

嗯,这是一种方法。假设您有一个函数g,它将最后两个值作为输入并生成下一个值。

(defn f [g x0 x1] 
  (let [s (g x0 x1)] 
    [s (fn [] (f g x1 s))]))

给定g和序列中的两个连续值,f返回由下一个值组成的对和一个将在此之后返回值的函数。您可以按如下方式使用f生成此类对的无限序列:

(iterate (fn [[v h]] (h)) (f g x0 x1))

要仅提取序列值,请执行以下操作:

(map first (iterate (fn [[v h]] (h)) (f g x0 x1)))

例如:

user=> (take 10 (map first (iterate (fn [[v h]] (h)) (f + 0 1))))
(1 2 3 5 8 13 21 34 55 89)

答案 2 :(得分:1)

您可以iterate使用两个元素的向量,然后获取结果序列的first

例如,要创建斐波纳契系列:

user=> (def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))
#'user/fib

user=> (take 10 fib)
(1 1 2 3 5 8 13 21 34 55)