进度报告的惯用clojure? [英] Idiomatic clojure for progress reporting?

查看:103
本文介绍了进度报告的惯用clojure?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何监控clojure中映射函数的进度?



在命令式语言中处理记录时,我经常每隔一段时间打印一条消息,事情已经走了,例如报告每1000个记录。基本上这是计数循环重复。



我想知道在clojure中我可以采取什么方法,我在我的记录的序列映射一个函数。在这种情况下,打印信息(甚至保持进度)似乎是基本副作用。



我到目前为止看到的样子: / p>

 (defn report 
[report-every val cnt]
(if(= 0 -every))
(printlnDonecnt))
val)

(report-progress
[report-every aseq]
map(fn [val cnt]
(报告报告 - 每个val cnt))
aseq
(iterate inc 1)))

例如:

  user>(doall(report-progress 2 )))
完成2
完成4
完成6
完成8
完成10
(0 1 2 3 4 5 6 7 8 9)

有其他更好的方法来实现这种效果吗?



我在做什么有什么缺陷? (我认为我保持懒惰,而不是抱着头)例如。

解决方案

clojure的伟大的事情,向数据本身报告,而不是计算的代码。这允许您分离这些逻辑上不同的部分。这里是我misc.clj的一个块,我发现我在几乎每个项目使用:

 (defn seq-counter 
在序列中的每个第n个条目之后调用回调
可选地,一旦seq被完全评估,就调用另一个回调。
([sequence n callback]
map#(do(if(=(rem%1 n)0)(callback))%2)(iterate inc 1)sequence)
-last(lazy-cat(seq-counter sequence n callback)
(lazy-seq(cons(finished-callback)()))))))
pre>

然后将记者包围您的数据,然后将结果传递给处理函数。

 (map process-data(seq-counter inc-progress input))


How should I monitor the progress of a mapped function in clojure?

When processing records in an imperative language I often print a message every so often to indicate how far things have gone, e.g. reporting every 1000 records. Essentially this is counting loop repetitions.

I was wondering what approaches I could take to this in clojure where I am mapping a function over my sequence of records. In this case printing the message (and even keeping count of the progress) seem to be essentially side-effects.

What I have come up with so far looks like:

(defn report
  [report-every val cnt]
  (if (= 0 (mod cnt report-every))
     (println "Done" cnt))
  val)

(defn report-progress
  [report-every aseq]
  (map (fn [val cnt] 
          (report report-every val cnt)) 
       aseq 
       (iterate inc 1)))

For example:

user> (doall (report-progress 2 (range 10)))
Done 2
Done 4
Done 6
Done 8
Done 10
(0 1 2 3 4 5 6 7 8 9)

Are there other (better) ways of achieving this effect?

Are there any pitfalls in what I am doing? (I think I am preserving laziness and not holding the head for example.)

解决方案

The great thing about clojure is you can attach the reporting to the data itself instead of the code that does the computing. This allows you to separate these logically distinct parts. Here is a chunk from my misc.clj that I find I use in just about every project:

(defn seq-counter 
  "calls callback after every n'th entry in sequence is evaluated. 
  Optionally takes another callback to call once the seq is fully evaluated."
  ([sequence n callback]
     (map #(do (if (= (rem %1 n) 0) (callback)) %2) (iterate inc 1) sequence))
  ([sequence n callback finished-callback]
     (drop-last (lazy-cat (seq-counter sequence n callback) 
                  (lazy-seq (cons (finished-callback) ())))))) 

then wrap the reporter around your data and then pass the result to the processing function.

(map process-data (seq-counter inc-progress input))

这篇关于进度报告的惯用clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆