0

I have a hash that looks like

{
 "lt"=>"456",
 "c"=>"123",
 "system"=>{"pl"=>"valid-player-name", "plv"=>"player_version_1"},
 "usage"=>{"trace"=>"1", "cq"=>"versionid", "stream"=>"od", 
 "uid"=>"9", "pst"=>[["0", "1", "10"]], "dur"=>"0", "vt"=>"2"}
}

How can I go about turning it into a hash that looks like

{
 "lt"=>"456",
 "c"=>"123",
 "pl"=>"valid-player-name", 
 "plv"=>"player_version_1",
 "trace"=>"1", 
 "cq"=>"versionid", 
 "stream"=>"od", 
 "uid"=>"9", 
 "pst"=>[["0", "1", "10"]], "dur"=>"0", "vt"=>"2"
}

I basically want to get rid of the keys system and usage and keep what's nested inside them

1
  • Just to mention, there's an } additional in your expected ouput. Commented Jun 27, 2017 at 14:20

5 Answers 5

2

"Low-tech" version :)

h = { ... }
h.merge!(h.delete('system'))
h.merge!(h.delete('usage'))
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Sergio, always love a low tech version :-), i thought delete would have deleted the whole nested hash, should have tried harder :-(
I know, let myself down a bit there really, thanks for the help
1

Assuming no rails:

hash.reject { |key, _| %w(system usage).include? key }.merge(hash['system']).merge(hash['usage'])

With active support:

hash.except('system', 'usage').merge(hash['system']).merge(hash['usage'])

Comments

1

A more generic version.

Merge any key that contains a hash:

h = { ... }

hnew = h.inject(h.dup) { |h2, (k, v)|
  h2.merge!(h2.delete(k)) if v.is_a?(Hash)
  h2
}

Comments

1

Assuming that your data has the same structure each time, I might opt for something simple and easy to understand like this:

def manipulate_hash(h)
  {
    "lt" => h["lt"],
    "c" => h["c"],
    "pl" => h["system"]["pl"],
    "plv" => h["system"]["plv"],
    "trace" => h["usage"]["trace"],
    "cq" => h["usage"]["cq"],
    "stream" => h["usage"]["stream"],
    "uid" => h["uid"],
    "pst" => h["pst"],
    "dur" => h["dur"],
    "vt" => h["vt"]
  }
end

I chose to make the hash using one big hash literal expression that spans multiple lines. If you don't like that, you could build it up on multiple lines like this:

def manipulate_hash
  r = {}
  r["lt"] = h["lt"]
  r["c"] = h["c"]
  ...
  r
end

You might consider using fetch instead of the [] angle brackets. That way, you'll get an exception if the expected key is missing from the hash. For example, replace h["lt"] with h.fetch("lt").

Comments

0

If you plan to have an arbitrarily large list of keys to merge, this is an easily scaleable method:

["system", "usage"].each_with_object(myhash) do |key|
  myhash.merge!(myhash.delete(key))
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.