Re: possibly non-intuitive behaviour of clojure.set/rename-keys and possible enhancement suggestion
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
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
> (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
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
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