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 <[email protected]>
> 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 <[email protected]>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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.