what is the best way to update / calculate a variable during doseq?
Obviously I could just do the following:
(doseq [x xs]
(println (string/join " " x)))
(println "total:" (reduce + 0 (map count xs)))
But I want to avoid having to map over the entire list at the end to calculate a value... It makes more sense to just update a count as we iterate.
I found that this works , but it seems like a bit of a cludge.
(defn display-xs [xs]
;; all I want to do is update a count while I print,
;; and have that value available afterwards!
(let [n (ref 0)]
(do
(doseq [x xs]
(dosync
(ref-set n (+ @n (count x)))
(println (string/join " " x))))
(println "total:" @n))))
I know that doseq
allows for :let
but I need the value after doseq is finished.
Or
(println "total:" (reduce (fn [m x] (do (println x) (+ m (count x)))) 0 xs))
You should not worry about the at most miniscule overhead of looping. It is much more important to separate different tasks. I quite like your first version.
Your second version could look better, but I'd still prefer the first.
(defn display-xs [xs]
(let [n (atom 0)]
(doseq [x xs]
(swap! n + (count x))
(println (string/join " " x)))
(println "total: " @n)))
I rewrote your code a little bit so show how I would do it:
(def sample-vals (repeatedly 10 #(range (+ 5 (rand-int 10)))))
(defn display-xs [xs]
(let [n (atom 0)]
(doseq [x xs]
(swap! n + (count x))
(println x))
(println "total:" @n)))
(newline)
(display-xs sample-vals)
(defn print-n-sum [cum coll]
(let [cnt (count coll) ]
(printf "%4d: " cnt)
(println coll)
(+ cum cnt)))
(defn calc-sum [xs]
(let [n (reduce print-n-sum 0 xs) ]
(println "total:" n)))
(newline)
(calc-sum sample-vals)
with result
> rs; lein run
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9 10 11)
(0 1 2 3 4 5 6 7 8 9 10)
(0 1 2 3 4 5 6 7 8 9 10 11)
(0 1 2 3 4)
(0 1 2 3 4 5 6 7 8 9 10 11)
(0 1 2 3 4 5)
(0 1 2 3 4 5 6 7 8 9 10)
(0 1 2 3 4 5 6)
(0 1 2 3 4 5 6 7 8 9 10)
total: 97
10: (0 1 2 3 4 5 6 7 8 9)
12: (0 1 2 3 4 5 6 7 8 9 10 11)
11: (0 1 2 3 4 5 6 7 8 9 10)
12: (0 1 2 3 4 5 6 7 8 9 10 11)
5: (0 1 2 3 4)
12: (0 1 2 3 4 5 6 7 8 9 10 11)
6: (0 1 2 3 4 5)
11: (0 1 2 3 4 5 6 7 8 9 10)
7: (0 1 2 3 4 5 6)
11: (0 1 2 3 4 5 6 7 8 9 10)
total: 97
Note that you don't have to use an atom (simpler than a ref for this example). You could do the printing and adding in a single function like print-n-sum
that you feed to reduce
.
You can print it in your reduce append function
(defn print-and-append [acc x]
(println (string/join " " x))
(+ acc (count x)))
(println (reduce print-and-append 0 xs))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.