Best way to replace hash keys

A

Alex Allmont

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 has=
h 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 =3D> repla=
ce } pairs,
# convert any String keys to a Regexp.
newPairs =3D { }
searchReplacePairs.delete_if do |search, replace|=20
if search.class =3D=3D String
newPairs[Regexp.new(search)] =3D replace
end
end
searchReplacePairs.merge! newPairs

Many thanks,
Alex
 
H

Harry Kakueki

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 h=
ash before merging them back into the original hash. =A0Another approach wo=
uld to simply rebuild a whole new hash.
=A0# Contrived example: given searchReplacePairs hash of { search =3D> re= place } pairs,
=A0# convert any String keys to a Regexp.
=A0newPairs =3D { }
=A0searchReplacePairs.delete_if do |search, replace|
=A0 =A0if search.class =3D=3D String
=A0 =A0 =A0newPairs[Regexp.new(search)] =3D replace
=A0 =A0end
=A0end
=A0searchReplacePairs.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 =3D {"ONE"=3D>"1",2=3D>"2","THREE"=3D>"3"}

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




Harry
 
I

Intransition

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 h=
ash before merging them back into the original hash. =A0Another approach wo=
uld to simply rebuild a whole new hash.
=A0 # Contrived example: given searchReplacePairs hash of { search =3D> r= eplace } pairs,
=A0 # convert any String keys to a Regexp.
=A0 newPairs =3D { }
=A0 searchReplacePairs.delete_if do |search, replace|
=A0 =A0 if search.class =3D=3D String
=A0 =A0 =A0 newPairs[Regexp.new(search)] =3D replace
=A0 =A0 end
=A0 end
=A0 searchReplacePairs.merge! newPairs

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'

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

See http://rubydoc.info/github/rubyworks/facets/master/Hash#rekey-instance_=
method

It's one of my favorite core extensions.
 
I

Intransition

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

Here's an alternative:

=A0 require 'facets/hash/rekey'

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

Slight correction:

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

Which gives me an idea about a possible improvement to the method ;-)
 
A

Alex Allmont

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 gi=
ves 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 inef=
ficient. Always interested in seeing alternative uses though :)

Best wishes,
Alex



-----Original Message-----
From: (e-mail address removed) [mailto:[email protected]] On Behalf Of Avdi Gr=
imm
Sent: 04 June 2011 22:52
To: ruby-talk ML
Subject: Re: 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 wrote an article about this back in 2009:
http://avdi.org/devblog/2009/11/20/hash-transforms-in-ruby/

Hope it's helpful.

--=20
Avdi Grimm
http://avdi.org
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top