# Best way to replace hash keys

**URL:** <https://rubytalk.org/t/best-way-to-replace-hash-keys/62861>\
**Category:** ruby-talk\
**Created:** [3 June 2011 14:27 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861 "2011-06-03T14:27:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Allmont](https://avatars.discourse-cdn.com/v4/letter/a/aeb1de/32.png) [@Alex\_Allmont](https://rubytalk.org/u/Alex_Allmont)\
**Post date:** [3 June 2011 14:27 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/1 "2011-06-03T14:27:33Z")

</div>

What is the most optimal and neatest way to replace keys in a hash given a particular condition?

I'm currently using delete\_if and putting replacement values into a new hash before merging them back into the original hash. Another approach would to simply rebuild a whole new hash.

&nbsp;&nbsp;# Contrived example: given searchReplacePairs hash of { search =\> replace } pairs,  
&nbsp;&nbsp;# convert any String keys to a Regexp.  
&nbsp;&nbsp;newPairs = { }  
&nbsp;&nbsp;searchReplacePairs.delete\_if do |search, replace|  
&nbsp;&nbsp;&nbsp;&nbsp;if search.class == String  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newPairs[Regexp.new(search)] = replace  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
&nbsp;&nbsp;searchReplacePairs.merge! newPairs

Many thanks,  
Alex

---

<div class="post-metadata">

**Author:** ![Harry3](https://avatars.discourse-cdn.com/v4/letter/h/54ee81/32.png) [@Harry3](https://rubytalk.org/u/Harry3)\
**Post date:** [4 June 2011 09:06 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/2 "2011-06-04T09:06:15Z")

</div>

I won't claim this is the best way but it may be worth a look.  
Is it doing what you want or did I misunderstand?

a = {"ONE"=\>"1",2=\>"2","THREE"=\>"3"}

t = a.to\_a.transpose  
b = Hash[\*(t[0].map{|x| x.class==String ? Regexp.new(x) :x}.zip(t[1])).flatten]  
p b #\> {/ONE/=\>"1", 2=\>"2", /THREE/=\>"3"}

Harry

> **···**
>
> On Fri, Jun 3, 2011 at 11:27 PM, Alex Allmont \<Alex.Allmont@naturalmotion.com\> wrote:
> 
> > What is the most optimal and neatest way to replace keys in a hash given a particular condition?
> > 
> > I'm currently using delete\_if and putting replacement values into a new hash before merging them back into the original hash. Another approach would to simply rebuild a whole new hash.
> > 
> > # Contrived example: given searchReplacePairs hash of { search =\> replace } pairs,  
> > # convert any String keys to a Regexp.  
> > newPairs = { }  
> > searchReplacePairs.delete\_if do |search, replace|  
> > if search.class == String  
> > newPairs[Regexp.new(search)] = replace  
> > end  
> > end  
> > searchReplacePairs.merge! newPairs
> > 
> > Many thanks,  
> > Alex

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [4 June 2011 12:35 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/3 "2011-06-04T12:35:47Z")

</div>

I'm not sure your example actually works, I think you'll end up with  
both string AND regexp keys.

Here's an alternative:

&nbsp;&nbsp;require 'facets/hash/rekey'

searchReplacePairs.rekey! do |search, replace|  
search.class == String ? Regexp.new(search) : search  
end

See [http://rubydoc.info/github/rubyworks/facets/master/Hash#rekey-instance\_method](http://rubydoc.info/github/rubyworks/facets/master/Hash#rekey-instance_method)

It's one of my favorite core extensions.

> **···**
>
> On Jun 3, 10:27 am, Alex Allmont \<Alex.Allm...@naturalmotion.com\> wrote:
> 
> > What is the most optimal and neatest way to replace keys in a hash given a particular condition?
> > 
> > I'm currently using delete\_if and putting replacement values into a new hash before merging them back into the original hash. Another approach would to simply rebuild a whole new hash.
> > 
> > # Contrived example: given searchReplacePairs hash of { search =\> replace } pairs,  
> > # convert any String keys to a Regexp.  
> > newPairs = { }  
> > searchReplacePairs.delete\_if do |search, replace|  
> > if search.class == String  
> > newPairs[Regexp.new(search)] = replace  
> > end  
> > end  
> > searchReplacePairs.merge! newPairs

---

<div class="post-metadata">

**Author:** ![Avdi\_Grimm2](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@Avdi\_Grimm2](https://rubytalk.org/u/Avdi_Grimm2)\
**Post date:** [4 June 2011 21:52 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/4 "2011-06-04T21:52:10Z")

</div>

I wrote an article about this back in 2009:

> **[Hash Transforms in Ruby - avdi.codes](https://avdi.codes/hash-transforms-in-ruby/)**
>
> I often find myself wanting to perform some kind of transform on a Ruby Hash which results in another Hash. For instance, converting all keys to strings. Ruby's built-in Hash methods make this a little inconvenient, because all the standard...

Hope it's helpful.

> **···**
>
> On Fri, Jun 3, 2011 at 10:27 AM, Alex Allmont \<Alex.Allmont@naturalmotion.com\> wrote:
> 
> > What is the most optimal and neatest way to replace keys in a hash given a particular condition?
> 
> --  
> Avdi Grimm
> 
> > **[Avdi Grimm, Code Cleric](https://avdi.codes)**
> >
> > Avdi Grimm, Code Cleric

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [4 June 2011 12:39 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/5 "2011-06-04T12:39:13Z")

</div>

Slight correction:

&nbsp;&nbsp;searchReplacePairs.rekey! do |search|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;search.class == String ? Regexp.new(search) : search  
&nbsp;&nbsp;&nbsp;end

Which gives me an idea about a possible improvement to the method 😉

> **···**
>
> On Jun 4, 8:35 am, Intransition \<transf...@gmail.com\> wrote:
> 
> > I'm not sure your example actually works, I think you'll end up with  
> > both string AND regexp keys.
> > 
> > Here's an alternative:
> > 
> > require 'facets/hash/rekey'
> > 
> > searchReplacePairs.rekey! do |search, replace|  
> > search.class == String ? Regexp.new(search) : search  
> > end

---

<div class="post-metadata">

**Author:** ![Alex\_Allmont](https://avatars.discourse-cdn.com/v4/letter/a/aeb1de/32.png) [@Alex\_Allmont](https://rubytalk.org/u/Alex_Allmont)\
**Post date:** [7 June 2011 10:12 UTC](https://rubytalk.org/t/best-way-to-replace-hash-keys/62861/6 "2011-06-07T10:12:33Z")

</div>

Thanks to everyone for the responses.

I'll probably work with rekey because of the clean syntax, very readable. Plus that extension generally looks very useful.

Thanks for the link Avdi, I've been struggling with using inject so this gives great insight.

I am picking apart Harry's example but I find it hard to read and I wonder if the array conversion, transposing, zipping, and flattening would be inefficient. Always interested in seeing alternative uses though 🙂

Best wishes,  
Alex

> **···**
>
> -----Original Message-----  
> From: avdi@inbox.avdi.org [mailto:avdi@inbox.avdi.org] On Behalf Of Avdi Grimm  
> Sent: 04 June 2011 22:52  
> To: ruby-talk ML  
> Subject: Re: Best way to replace hash keys
> 
> On Fri, Jun 3, 2011 at 10:27 AM, Alex Allmont \<Alex.Allmont@naturalmotion.com\> wrote:
> 
> > What is the most optimal and neatest way to replace keys in a hash given a particular condition?
> 
> I wrote an article about this back in 2009:
> 
> > **[Hash Transforms in Ruby - avdi.codes](https://avdi.codes/hash-transforms-in-ruby/)**
> >
> > I often find myself wanting to perform some kind of transform on a Ruby Hash which results in another Hash. For instance, converting all keys to strings. Ruby's built-in Hash methods make this a little inconvenient, because all the standard...
> 
> Hope it's helpful.
> 
> --  
> Avdi Grimm
> 
> > **[Avdi Grimm, Code Cleric](https://avdi.codes)**
> >
> > Avdi Grimm, Code Cleric
