Home > Mobile >  Replace all HASH keys with another key
Replace all HASH keys with another key

Time:08-25

I'm trying to replace all the keys inside a hash with another key, like this:

{
  name: 'Josh',
  surname: 'Simon',
  cars: [{
    name: 'Diablo',
    seats: [{ name: 'Josh', surname: 'Simon' }],
  },
  {
    name: 'Raptor',
    seats: [{ name: 'Josh', surname: 'Simon' }],
  },
  {
    name: 'Testarossa',
    seats: [{ name: 'Josh', surname: 'Simon' }],
  }],
}

let's say I want to change the cars key to people, so I can achieve something like this

{
  name: 'Josh',
  surname: 'Simon',
  cars: [{
    name: 'Diablo',
    people: [{ name: 'Josh', surname: 'Simon' }],
  },
  {
    name: 'Raptor',
    people: [{ name: 'Josh', surname: 'Simon' }],
  },
  {
    name: 'Testarossa',
    people: [{ name: 'Josh', surname: 'Simon' }],
  }],
}

can this be done somehow?

CodePudding user response:

You can delete old key and assign that value to new one

hash =
  {
    name: 'Josh',
    surname: 'Simon',
    cars: [{
      name: 'Diablo',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    },
    {
      name: 'Raptor',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    },
    {
      name: 'Testarossa',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    }],
  }
hash[:cars].each { |h| h[:people] = h.delete(:seats) }
hash

# => {
#      name: 'Josh',
#      surname: 'Simon',
#      cars: [{
#        name: 'Diablo',
#        people: [{ name: 'Josh', surname: 'Simon' }],
#      },
#      {
#        name: 'Raptor',
#        people: [{ name: 'Josh', surname: 'Simon' }],
#      },
#      {
#        name: 'Testarossa',
#        people: [{ name: 'Josh', surname: 'Simon' }],
#      }],
#    }  

CodePudding user response:

If the variable hash holds the hash given in the example, and that object is to be mutated, one can write the following.

hash[:cars].each { |h| h.transform_keys! { |k| k == :seats ? :people : k } }
  #=> [
  #    {
  #     :name=>"Diablo",
  #     :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #    },
  #    {
  #     :name=>"Raptor",
  #     :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #    },
  #    {
  #     :name=>"Testarossa",
  #     :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #    }
  #   ]

​so now

hash
  #=> {
  #    :name=>"Josh",
  #    :surname=>"Simon",
  #    :cars=>[
  #      {
  #       :name=>"Diablo",
  #       :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #      },
  #      {
  #       :name=>"Raptor",
  #       :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #      },
  #      {
  #       :name=>"Testarossa",
  #       :people=>[{:name=>"Josh", :surname=>"Simon"}]
  #      } 
  #    ]
  #   }

See Hash#transform_keys!.


If the hash is not to be mutated you could operate on a deep copy. One of doing that is to use the methods Marshal::load and Marshal::dump:

h = Marshal.load(Marshal.dump(hash))
  #=> {
  #    :name=>"Josh",
  #    :surname=>"Simon",
  #    :cars=>[
  #      {
  #       :name=>"Diablo",
  #       :seats=>[{:name=>"Josh", :surname=>"Simon"}]
  #      },
  #      {
  #       :name=>"Raptor",
  #       :seats=>[{:name=>"Josh", :surname=>"Simon"}]
  #      },
  #      {
  #        :name=>"Testarossa",
  #        :seats=>[{:name=>"Josh", :surname=>"Simon"}]
  #      }
  #    ]
  #   }

Note that if we alter h by writing, for example,

h[:name] = "Lola"
h[:cars][1][:seats][0] = "cats"

we may verify that hash is unchanged.

CodePudding user response:

You can do it like this:

hash =
  {
    name: 'Josh',
    surname: 'Simon',
    cars: [{
      name: 'Diablo',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    },
    {
      name: 'Raptor',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    },
    {
      name: 'Testarossa',
      seats: [{ name: 'Josh', surname: 'Simon' }],
    }],
  }

hash[:cars].each { |record| record.store(:people, record.delete(:seats)) }
  • Related