【发布时间】:2016-08-03 07:52:41
【问题描述】:
我正在从事一个个人市场分析项目。我有一个代表市场最近所有转折点的数据结构,如下所示:
[{:high 1.121455, :time "2016-08-03T05:15:00.000000Z"}
{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}
{:high 1.12173, :time "2016-08-03T04:30:00.000000Z"}
{:high 1.121925, :time "2016-08-03T00:00:00.000000Z"}
{:high 1.12215, :time "2016-08-02T23:00:00.000000Z"}
{:high 1.12273, :time "2016-08-02T21:15:00.000000Z"}
{:high 1.12338, :time "2016-08-02T18:15:00.000000Z"}
{:low 1.119215, :time "2016-08-02T12:30:00.000000Z"}
{:low 1.118755, :time "2016-08-02T12:00:00.000000Z"}
{:low 1.117575, :time "2016-08-02T06:00:00.000000Z"}
{:low 1.117135, :time "2016-08-02T04:30:00.000000Z"}
{:low 1.11624, :time "2016-08-02T02:00:00.000000Z"}
{:low 1.115895, :time "2016-08-01T21:30:00.000000Z"}
{:low 1.11552, :time "2016-08-01T11:45:00.000000Z"}
{:low 1.11049, :time "2016-07-29T12:15:00.000000Z"}
{:low 1.108825, :time "2016-07-29T08:30:00.000000Z"}
{:low 1.10839, :time "2016-07-29T08:00:00.000000Z"}
{:low 1.10744, :time "2016-07-29T05:45:00.000000Z"}
{:low 1.10716, :time "2016-07-28T19:30:00.000000Z"}
{:low 1.10705, :time "2016-07-28T18:45:00.000000Z"}
{:low 1.106875, :time "2016-07-28T18:00:00.000000Z"}
{:low 1.10641, :time "2016-07-28T05:45:00.000000Z"}
{:low 1.10591, :time "2016-07-28T01:45:00.000000Z"}
{:low 1.10579, :time "2016-07-27T23:15:00.000000Z"}
{:low 1.105275, :time "2016-07-27T22:00:00.000000Z"}
{:low 1.096135, :time "2016-07-27T18:00:00.000000Z"}]
从概念上讲,我想匹配:high/:low 对,计算出价格范围(高低)和中点(高低的平均值),但我不希望每个可能的对都是生成。
我想做的是从集合{:high 1.121455, :time "2016-08-03T05:15:00.000000Z"} 中的第一个项目开始,然后“向下”遍历集合的其余部分,与每个 :low 项目创建一对,直到我点击下一个 :high 项目.一旦我点击了下一个:high 项目,我对任何其他配对都不感兴趣。在这种情况下,只创建了一对,即:high 和第一个:low - 我停在那里,因为下一个(第三个)项目是:high。生成的 1 条记录应类似于 {:price-range 0.000365, :midpoint 1.121272, :extremes [{:high 1.121455, :time "2016-08-03T05:15:00.000000Z"}{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}]}
接下来,我将移动到集合 {:low 1.12109, :time "2016-08-03T05:15:00.000000Z"} 中的第二个项目,然后“向下”遍历集合的其余部分,与每个 :high 项目创建一对,直到我点击下一个 :low 项目。在这种情况下,我生成了 5 条新记录,分别是 :low 和接下来的 5 个 :high 项目,它们都是连续的;这 5 条记录中的第一个看起来像
{:price-range 0.000064, :midpoint 1.12131, :extremes [{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}{:high 1.12173, :time "2016-08-03T04:30:00.000000Z"}]}
这 5 条记录中的第二条看起来像
{:price-range 0.000835, :midpoint 1.1215075, :extremes [{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}{:high 1.121925, :time "2016-08-03T00:00:00.000000Z"}]}
等等。
在那之后,我收到了一个:low,所以我停在那里。
然后我会移动到第三个项目{:high 1.12173, :time "2016-08-03T04:30:00.000000Z"} 并走“下”与每个:low 创建对,直到我点击下一个:high。在这种情况下,我生成了 0 对,因为 :high 后面紧跟着另一个 :high。接下来的 3 个 :high 项也是如此,所有这些项都紧随其后的是另一个 :high
接下来我会看到第 7 个项目 {:high 1.12338, :time "2016-08-02T18:15:00.000000Z"},它应该与以下 20 个 :low 项目中的每一个生成一对。
我生成的结果将是创建的所有对的列表:
[{:price-range 0.000365, :midpoint 1.121272, :extremes [{:high 1.121455, :time "2016-08-03T05:15:00.000000Z"}{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}]}
{:price-range 0.000064, :midpoint 1.12131, :extremes [{:low 1.12109, :time "2016-08-03T05:15:00.000000Z"}{:high 1.12173, :time "2016-08-03T04:30:00.000000Z"}]}
...
如果我使用 Python 之类的东西来实现它,我可能会使用几个嵌套循环,当我不再看到 :highs 与我的 :low 配对时,使用 break 退出内部循环反之亦然,并在我遍历 2 个循环时将所有生成的记录累积到一个数组中。我只是想不出一个使用 Clojure 攻击它的好方法......
有什么想法吗?
【问题讨论】:
-
一般建议:将问题分解为小函数并查看
reduce/reduced+ 用法示例。 -
这是常见的面试问题“直方图能容纳多少水”的另一种形式,我想我会用这个来让人们更抽象地思考它
-
继续使用你的嵌套循环和中断。在 Clojure 中,您通常会改用
loop和recur
标签: clojure destructuring