4 ms·
I was going to complain that parts of the article were disjointed and contradictory (Use -->, don't use -->, JK use it) until I noticed the name of the blog is
by shasta 16y ago
I was going to complain that parts of the article were disjointed and contradictory (Use -->, don't use -->, JK use it) until I noticed the name of the blog is "Two Guys Arguing."
Solution from the comments: (apply merge-with + (map (fn [c] {c 1}) “abcdaabccc”))
- runevault 16y agoIt always amazes me how many people either never noticed merge-with or simply don't use it. Having done something similar with a list of words (created via regex parsed over a file) I adore what you can do with it. Especially if you use transients. Unless of course they just didn't think of the fact strings are seqs in clojure by default. edit: I could be crazy, but one problem with using apply is you force the realization of your object, so while in THIS case it's fine, using larger amount of data would cause a problem. IIRC more space sane way to do this is use (reduce {} (merge-with + %) list) and man I MUST be rusty, I can't remember if the default value comes before or after the function, and no repl handy. Hopefully the point is gotten across :)
- runevault 16y agoReplying to myself. Just googled it and I had the code wrong shame (defn count-words [coll] (reduce #(merge-with + %1 {%2 1}) {} coll))
- jared314 16y agoLooking from the outside in, clojure has too many useful/amazing functions to learn in an afternoon, weekend, or a month. So, not using something you don't understand is perfectly valid in my opinion.
- ataggart 16y agoThe problem with the latter solution is that apply isn't lazy. The more correct solution would be a simple reduce: (reduce #(update-in %1 [%2] (fnil inc 0)) {} "abcdaabccc")
- runevault 16y agoI wonder if update-in or merge-with would be more efficient. Another thing to consider is if you want to get fancy (persistent! (reduce #(update-in %1 [%2] (fnil inc 0)) (transient {}) "abcdaabccc")) Still no REPL but this should work and take advantage of transients if you're doing it against a bigger dataset (which I assume you care about since you also worried about laziness)
- deleted 16y ago[deleted]
- praptak 16y agoApply itself is lazy. This: (apply f infinite-lazy-list) does not force evaluation of the infinite-lazy-list, if the f itself does not force it. My favorite example is (apply concat ...), which can be used to flatten an infinite sequence of sequences (concat is lazy wrt to its argument list, so this works.)