Laurent, your approach doesn't quite work:
=> (uniquify ["a_1" "a" "a"] (fn [s n] (str s \_ n)))
["a_1" "a" "a_1"]



On Fri, Jan 10, 2014 at 1:34 PM, Laurent PETIT <laurent.pe...@gmail.com>wrote:

> okay, new take solving the issue raised by Mark:
>
> (defn uniquify [in format-fn]
>   (loop [[item :as in] (seq in)
>          {n item :as item-nbrs} {}
>          out []]
>     (if-not in
>       out
>       (let [format-fn (if n format-fn (constantly item))
>             new-item (format-fn item n)]
>         (recur (next in)
>                (merge-with (fnil + 0)
>                            item-nbrs
>                            (hash-map item 1 new-item 1))
>                (conj out new-item))))))
>
> => (uniquify ["a" "b" "c" "a" "a_1" "a_1" "a"] #(str %1 "_" %2))
> ["a" "b" "c" "a_1" "a_1_1" "a_1_2" "a_2"]
>
>
>
> 2014/1/10 Colin Yates <colin.ya...@gmail.com>
>
>> 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.
>>
>
>  --
> --
> 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.

Reply via email to