首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哈希向量中的值增加了吗?

哈希向量中的值增加了吗?
EN

Stack Overflow用户
提问于 2014-02-04 07:22:56
回答 4查看 129关注 0票数 1

新手克洛尔问题警报..。

我有一个Clojure向量,它看起来如下所示:

代码语言:javascript
复制
(def sample-data
  [{:date "2014-01-01" :value 5}
   {:date "2014-01-02" :value 7}
   {:date "2014-01-03" :value 6}
   {:date "2014-01-04" :value 7}
   {:date "2014-01-07" :value 11}])

实际上它比那个要大得多,但你有个大致的想法.-它是一个单一值的向量,每天收集一次。向量将按:日期顺序排序,但对于奇数缺失的样本,存在空白。

我想要创建一个函数,它在'sample-data‘中接受一个:date,并告诉我:那个日期的值大于前一个日期的:value。拐角处案件:

  • 如果在前一个日期没有样本,那么我想回到收集样本的最后一个日期,然后与它进行比较:value
  • 如果指定日期的值为no :value,则我很乐意在其他地方引发错误并处理它
  • 如果两个:值相等,我想返回false (因为它没有增加)

我想把这个函数称为。

代码语言:javascript
复制
(value-increased? sample-data {:date '2014-01-03'})

得到一个布尔响应。在这种情况下,它将是假的,因为2014-01-03 (6)的数值比前一天的值(7)要小。

提前感谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-04 08:06:15

代码语言:javascript
复制
(defn has-value-increased?
  [sample searched-date]
  (reduce (fn [_ [{:keys prev-value :value} {:keys [value date]}]]
            (if (and (= date searched-date)
                     (< prev-value value))
              (reduced true)))
          nil
          (partition 2 1 sample)))

注意,这可能效率很低,因为每次调用函数时都可以遍历整个示例。根据实际应用程序的不同,最好编写一个函数,收集值在一次传递中增加的所有日期,然后将其作为一组返回,然后将其作为函数调用,以检查日期是否增加。

以下是修改后的函数:

代码语言:javascript
复制
(defn collect-dates-with-increased-value
  [sample]
  (reduce (fn [acc [{prev-value :value} {:keys [date value]}]]
            (cond-> acc
              (< prev-value value) (conj date)))
          []
          (partition 2 1 sample)))

然后收集日期,例如在REPL:

代码语言:javascript
复制
=> (def dates-with-increased-value (set (collect-dates-with-increased-value sample-data)))
=> dates-with-increased-value
#{"2014-01-02" "2014-01-04" "2014-01-07"} 
=> (dates-with-increased-value "2014-01-02")
"2014-01-02"
=> (dates-with-increased-value "2014-01-03")
nil 
票数 2
EN

Stack Overflow用户

发布于 2014-02-04 08:06:31

您可以使用二进制搜索找到给定日期的索引,然后检查该索引中的条目和前面的条目。

或者,您也可以使用mikera的时间线库,它提供了一种数据结构,用于精确地维护这种类似向量的日志、时间戳值和在这些日志上操作的各种函数:

代码语言:javascript
复制
(require '[mikera.timeline :as tl])

(def t
  (-> (tl/timeline)
      ;; (tl/log timestamp value)
      (tl/log 0 0)
      (tl/log 86400000 1)))

然后,tl/seek允许您在给定时间之前找到最后一个条目的索引,而在给定索引处的条目可以用nth提取。

最后,clj时间对于指定时间(并且已经是时间的依赖关系)非常有用:

代码语言:javascript
复制
(tl/log (tl/timeline) (clj-time.core/now) :foo)
;= #<Timeline [[#<Instant 2014-02-04T08:00:08.290Z> :foo]]>
票数 4
EN

Stack Overflow用户

发布于 2014-02-04 08:21:58

如果您尝试这段代码,您可以注释(首先..)的每一行去看看哪一步能做什么。

代码语言:javascript
复制
(->>
  sample-data
  (filter :value)
  (map #(assoc % :date (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") (:date %))))
                     ;parse date
  (sort-by :date)
  (partition 2 1)    ;partition the sequence into every two consecutive days that have a :date value
  (map (fn [[f s]]   ;destructure vector into first day f and second day s 
         (conj s [:in-order (< (:value f) (:value s))])))
                     ;compare days, return second date with compare boolean in in :in-order key 
  (remove :in-order) ;filter where :in-order is false
  first              ;take first false :in-order, and stop processing
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21546342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档