I've been finding uses for Brandon Bloom's transduce mini-library left and right lately. There is a class of problems where you want to track some state as you process a seq, and transduce.lazy/map-state enables you to do that (https://github.com/brandonbloom/transduce).
Here's my solution using it. It is concise and stateless: (defn uniqify [coll] (map-state (fn [elem->times-seen x] (let [x (if-let [times-seen (elem->times-seen x)] (str x "_" times-seen) x) elem->times-seen' (update-in elem->times-seen [x] (fnil inc 0))] [elem->times-seen' x])) {} coll)) On Sat, Jan 11, 2014 at 12:32 AM, Mark Engelberg <mark.engelb...@gmail.com>wrote: > Very clever! > > > On Fri, Jan 10, 2014 at 8:10 PM, Håkan Råberg <hakan.rab...@gmail.com>wrote: > >> Another style, using channels for local state, but could been plain old >> iterators, slight golf warning: >> >> (require '[clojure.core.async :refer [to-chan <!!]]) >> >> (defn uniquify [s formatter] >> (let [g (memoize #(to-chan (cons % (map (partial formatter %) (next >> (range))))))] >> (map (fn f [x] ((some-fn #{x} f) (<!! (g x)))) s))) >> >> (uniquify ["a" "a" "a" "a" "b" "a_2" "a_3" "a_3_1" "a_3_1" "a"] #(str %1 >> "_" %2)) >> ;=> ["a" "a_1" "a_2" "a_3" "b" "a_2_1" "a_3_1" "a_3_1_1" "a_3_1_2" "a_4"] >> >> >> On Friday, 10 January 2014 14:59:10 UTC, Colin Yates wrote: >>> >>> I have a sequence of file names and I want to make them unique. >>> (uniquify ["a" "b" "c" "a"]) => ["a" "b" "c" "a_1"]) >>> >>> This is what I have come up with, but surely there is a better way? >>> >>> What would you all do? Feedback welcome (including the word 'muppet' as >>> I am sure I have missed something simple) :) >>> >>> (defn uniquify >>> "Return a sequence, in the same order as s containing every element >>> of s. If s (which is presumed to be a string) occurs more than once >>> then every subsequent occurrence will be made unique. >>> >>> Items will be updated to include an incrementing numeric count using >>> the specified formatter function. The formatter function will be >>> given the name and the number and should return a combination of the >>> two. >>> >>> The set of unique s's in the returned sequence will be the count of >>> s's in s." >>> ([s] (uniquify s (fn [item duplicates] (str item "_" duplicates)))) >>> ([s formatter] >>> (let [occurrences (atom {}) >>> register-occurrence (fn [item] >>> (if (get @occurrences item) >>> (swap! (get @occurrences item) inc) >>> (swap! occurrences assoc item (atom >>> 1))) >>> @(get @occurrences item)) >>> process (fn [item] >>> (let [duplicates (dec (register-occurrence item))] >>> (if (> duplicates 0) >>> (formatter item duplicates) >>> item))) >>> unique-s (map process s)] >>> unique-s))) >>> >> -- >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.