Re: possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion

2011-05-13 Thread Steve Miner
Using the array-map sounds like a good work-around when you know there are 
potential key collisions.  It would also allow you to swap keys reliably using 
a temporary key.

(rename-keys  {:a 1 :b 2 :c 3}  (array-map :a :tmp :b :a :tmp :b))
;; {:b 1, :a 2, :c 3}


The larger question is: Should rename-keys handle the collisions for you?  I 
think it was probably a pragmatic decision not to handle collisions in order to 
have better performance for the (usual) collision-free case with a small number 
of changes.  It would be good if the doc for rename-keys warned that behavior 
with key collisions is not defined.


On May 10, 2011, at 10:56 PM, Sunil S Nandihalli wrote:

> (defn rename-keys [mp kmap-fn]
>   (into {} (map (fn [[key val]] [(kmap-fn key) val]) mp)))

By the way, the suggested implementation doesn't work for keys that don't 
change (that is, when some keys that are left out of the kmap).  You get a nil 
for the key in that case.  I think it would work if the old key was used when 
you got a nil for the new key. However, you still have an issue if someone 
actually wants to use nil or false as a new key. (Not likely, but you'd need to 
document it.)

(defn truthy-rename-keys [mp kmap-fn]
  (into {} (map (fn [[key val]] [(or (kmap-fn key) key) val]) mp)))

I did a few timings and it looks like performance is similar for rename-keys 
and truthy-rename-keys when kmap has lots of key changes, but rename-keys is 
much faster when there are only a couple of key changes.  That makes sense as 
rename-keys is reducing over the kmap, but truthy-rename-keys is mapping over 
the original map.

My conclusion is that it's probably not worth "fixing" rename-keys.  A little 
extra documentation would be helpful.  I updated the ClojureDocs.org entry with 
a couple of new examples with key collisions.

Regards,
Steve Miner

-- 
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


Re: possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion

2011-05-11 Thread Armando Blancas
This renames keys to avoid collisions, using an array map to preserve
the order of the keys:

user=> (rename-keys {1 :a 2 :b 3 :c}  (array-map 3 4 2 3 1 2))
{2 :a, 3 :b, 4 :c}

On May 11, 7:22 am, Armando Blancas  wrote:
> > (clojure.set/rename-keys {1 :a 2 :b 3 :c}  {1 2 2 3 3 4})
>
> > returns
>
> > {4 :a}
>
> That's caused by the collision between new and existing keys. Renaming
> 1 to 2 blows [2 :b]: {2 :a, 3 :c}; then renaming 2 to 3 blows [3 :c],
> leaving {3 :a}; and the last just renames 3 to 4: {4 :a}.

-- 
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


Re: possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion

2011-05-11 Thread Armando Blancas
> (clojure.set/rename-keys {1 :a 2 :b 3 :c}  {1 2 2 3 3 4})
>
> returns
>
> {4 :a}

That's caused by the collision between new and existing keys. Renaming
1 to 2 blows [2 :b]: {2 :a, 3 :c}; then renaming 2 to 3 blows [3 :c],
leaving {3 :a}; and the last just renames 3 to 4: {4 :a}.

-- 
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


Re: possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion

2011-05-10 Thread Sunil S Nandihalli
I agree there are going to be problems with implementation as-well .. for
example if not all the keys in the current map are not in the kmap ... but
situation can be handled however, if we passed a function this is going to
be harder .. ..

On Wed, May 11, 2011 at 8:26 AM, Sunil S Nandihalli <
sunil.nandiha...@gmail.com> wrote:

> Hello everybody,
>  I tried to use clojure.set/rename-keys .. I kind of felt it has a little
> odd behaviour... for example ..
>
> (clojure.set/rename-keys {1 :a 2 :b 3 :c}  {1 2 2 3 3 4})
>
> returns
>
> {4 :a}
>
> I think a more reasonable behavior would be to have it return
>
> {2 :a 3 :b 4 :c}
>
> a further enhancement suggestion would be to accept a function instead of a
> map that way even the existing code will not break since the map already
> implements IFn
>
> a sample implementation which takes the above into account would be ..
>
> (defn rename-keys [mp kmap-fn]
>   (into {} (map (fn [[key val]] [(kmap-fn key) val]) mp)))
>
>
> Thanks,
> Sunil.
>

-- 
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

possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion

2011-05-10 Thread Sunil S Nandihalli
Hello everybody,
 I tried to use clojure.set/rename-keys .. I kind of felt it has a little
odd behaviour... for example ..

(clojure.set/rename-keys {1 :a 2 :b 3 :c}  {1 2 2 3 3 4})

returns

{4 :a}

I think a more reasonable behavior would be to have it return

{2 :a 3 :b 4 :c}

a further enhancement suggestion would be to accept a function instead of a
map that way even the existing code will not break since the map already
implements IFn

a sample implementation which takes the above into account would be ..

(defn rename-keys [mp kmap-fn]
  (into {} (map (fn [[key val]] [(kmap-fn key) val]) mp)))


Thanks,
Sunil.

-- 
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