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)) }