Best way to replace hash keys

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

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

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

See 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

I wrote an article about this back in 2009:

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

Slight correction:

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

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

···

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

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

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:

Hope it's helpful.

--
Avdi Grimm