8

我有以下问题:我有一个包含超过 10000 个条目的时间序列,我想对每个条目执行一些计算。仅此一项不会有问题,但我需要获得最后一个计算值才能获得下一个值。我需要的一个非常简单的形式如下所示:

Val(n) = Val(n-1) + (time-series-entry / 2) (或类似的东西!)

我不知道如何管理这个。简单地做这样的事情:

(defn calc-val
  [time-series element]
  (seq (cons (generate-val-element time-series element)
             (calc-val time-series (inc element)))))

不会工作,因为不能(至少我不知道怎么做!)得到最后的计算值。然后我想:好吧,让我们使用 Loop-Recur。这将为我提供与时间序列条目相对应的值,但对于下一个我将不得不再次进行所有计算。迭代是正确的,但它不起作用,因为该函数有副作用。

所以我被困在这里。如果有人能给我一个提示,那就太好了。

4

2 回答 2

7

如果您只关心最终结果,请使用reduce; 如果您需要获得依次转换每个值的结果序列(其中每个转换取决于之前的转换),请使用reductionsclojure.contrib.seq-utils在 1.1 和clojure.core1.2 中找到)。

下面,transform-first-entry对第一个条目做任何你想做的事情(如果你不需要以任何方式对其进行转换,你可以省略reduce/的第一个参数reductions并使用entries而不是(rest entries作为最后一个参数);transform-entry是获取转换前一个条目和当前条目(按此顺序)的结果并为当前条目生成转换结果的函数。

;;; only care about the final result
(reduce transform-entry
        (transform-first-entry (first series))
        (rest entries))

;;; need to get a seq of intermediate results
(reductions ...arguments as above...)

请注意,这reductions是懒惰的。

假设您想保持第一个条目不变并将示例转换从问题文本应用到后续条目,您可以使用

(defn transform-entry [prev-transformed current]
  (+ prev-transformed
     (/ current 2)))

作为归约函数

(reduce transform-entry series) ; ...or reductions
于 2010-07-13T14:49:29.867 回答
3

如果你只是想要一个提示;研究使用partition.

不仅仅是提示……</p>

(defn calc-val
  [time-series element]
  (let [p (partition 2 1 time-series)]
    (for [t p]
      (let [first-value (first t)
            second-value (second t)]
        (do whatever you need to here)))))

虽然这还没有经过测试,但它应该可以工作或接近工作:)

解释

(partition n i seq)分成seq长度列表n(在这种情况下为 2)和重叠i(在这种情况下为 1)的部分,然后我们用 迭代这些for部分,并对这些部分做我们想做的事情。

于 2010-07-13T14:22:31.177 回答