Best way to replace hash keys

Discussion in 'Ruby' started by Alex Allmont, Jun 3, 2011.

  1. Alex Allmont

    Alex Allmont Guest

    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
     
    Alex Allmont, Jun 3, 2011
    #1
    1. Advertisements

  2. ash before merging them back into the original hash. =A0Another approach wo=
    uld to simply rebuild a whole new hash.
    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
     
    Harry Kakueki, Jun 4, 2011
    #2
    1. Advertisements

  3. Alex Allmont

    Intransition Guest

    ash before merging them back into the original hash. =A0Another approach wo=
    uld to simply rebuild a whole new hash.
    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.
     
    Intransition, Jun 4, 2011
    #3
  4. Alex Allmont

    Intransition Guest

    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 ;-)
     
    Intransition, Jun 4, 2011
    #4
  5. Alex Allmont

    Avdi Grimm Guest

    Avdi Grimm, Jun 4, 2011
    #5
  6. Alex Allmont

    Alex Allmont Guest

    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: [mailto:] On Behalf Of Avdi Gr=
    imm
    Sent: 04 June 2011 22:52
    To: ruby-talk ML
    Subject: Re: Best way to replace hash keys

    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
     
    Alex Allmont, Jun 7, 2011
    #6
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.