Gosh - my public humiliation continues. Here is one that actually works: (first (reduce (fn [[results seen] item] (let [cnt (get seen item 0)] [(conj results (if (> cnt 0) (format-fn item cnt) item)) (assoc seen item (inc cnt))])) [[] {}] items)) (fact "strings can be made unique" (s/uniquify ["a" "b" "c"]) => ["a" "b" "c"] (s/uniquify ["a" "b" "a" "c" "b" "b" "b" "b" "a"]) => ["a" "b" "a_1" "c" "b_1" "b_2" "b_3" "b_4" "a_2"])
On Friday, 10 January 2014 20:59:00 UTC, Colin Yates wrote: > > Sorry - wrong c/p: > > (first (reduce (fn [[results seen] item] > (let [cnt (get seen item 0) > item (if (> cnt 0) (format-fn item cnt) item)] > [(conj results item) (assoc seen item (inc cnt))])) > [[] {}] > items)) > > On Friday, 10 January 2014 20:55:04 UTC, Colin Yates wrote: >> >> I thought I would have a go myself without copying (although having read >> them earlier) the other functions and this is what I came up with: >> >> (first (reduce (fn [[results seen] item] >> (let [occurrences ((fnil identity 0) (get seen >> item)) >> seen (assoc seen item (inc occurrences)) >> item (if (> occurrences 0) (format-fn item >> occurrences) item)] >> [(conj results item) seen])) [[] {}] (seq items))) >> >> This doesn't solve the problem you mention, but baby steps. >> >> Being really anal I could claim the original a_2 should remain a_2 and >> the third instance of a jump to being a_3. I thought about this and >> couldn't see how to do this with reduce because I really want to say "oh, I >> have a new name, recurse into the function again with the new proposed >> name", i.e. loop the generation of the proposed name until it is unique, >> but I haven't got that far yet (without potentially blowing the stack!) >> >> Then I saw your 'recur' used outside of a loop which points the way... >> >> Thanks! >> >> On Friday, 10 January 2014 20:16:28 UTC, puzzler wrote: >>> >>> >>> On Fri, Jan 10, 2014 at 11:52 AM, Colin Yates <colin...@gmail.com>wrote: >>> > way to take the wind out of our sails! Well spotted :). >>> >>> >>> It's not too hard to fix. Here's an adapted version of Jonas' solution >>> that should do the trick: >>> >>> (defn uniqueify [items] >>> (first >>> (reduce (fn [[results count-map] item] >>> (let [n (count-map item 0)] >>> (if (zero? n) >>> [(conj results item) (assoc count-map item (inc n))] >>> (recur [results (assoc count-map item (inc n))] >>> (str item \_ n))))) >>> [[] {}] >>> items))) >>> >>> => (uniqueify ["a" "a" "a" "a" "b" "a_2" "a_3" "a_3_1" "a_3_1" "a"]) >>> ["a" "a_1" "a_2" "a_3" "b" "a_2_1" "a_3_1" "a_3_1_1" "a_3_1_2" "a_4"] >>> >> -- -- 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.