简体   繁体   中英

How can I build a hash of hash from Hash of Hash of array in Ruby

I have following hash of hash of array with me:

Hash["signin"]["elementname"]["ids"]` -- here ids are "macid" and "winid"

Its structure is like elementname has two kind of ids macid and winid .

On runtime when I pass a parameter say mac then I am trying to build a hash from a existing hash which would have only macid . So that, I am trying to convert a Hash["signin"]["elementname"]["ids"] .

This should work

Hash[common_ids.map { |a|
  [a[0], Hash[a[1].map { |b|
    [b[0], b[1]['mac_id']]
  }]]
}]

You need to do the Hash[...] part because the map method on a hash turns it into an array of key-value pairs.

Hopefully that code works for you. It worked for me in irb. You may want to rename the a and b variables to something that makes more sense.

Here's some explanation:

When you call .map on a hash, it provides each value as a [k, v] array, it expects the contents of the block to evaluate to a [k, v] array, and the result returned by .map is an array of [k, v] arrays. Hash[...] is used to turn that style of array back into a hash (see http://ruby-doc.org/core-2.1.5/Hash.html#method-c-5B-5D ).

For

common_ids = {"signin"=> { "company_txt"=>{"mac_id"=> "mac_id_1", "win_id"=> "win_id_1"}, "username_txtbx"=> {"mac_id"=>"mac_id_2", "win_id"=>"win_id_2"} } }

here is what happens:

The first level block (with parameter a) gets

a = ["signin", { "company_txt"=>{"mac_id"=> "mac_id_1", "win_id"=> "win_id_1"}, "username_txtbx"=> {"mac_id"=>"mac_id_2", "win_id"=>"win_id_2"} }]

It calls map on the second entry of that array (the value part of the key-value pair) using the second block (with parameter b), which first gets

b = ["company_txt", {"mac_id"=> "mac_id_1", "win_id"=> "win_id_1"}]

It returns

["company_txt", "mac_id_1"]

Then it gets

b = ["username_txtbx", {"mac_id"=>"mac_id_2", "win_id"=>"win_id_2"}]

It returns

["username_txtbx", "mac_id_2"]

The result of this inner map is

[["company_txt", "mac_id_1"], ["username_txtbx", "mac_id_2"]]

Calling Hash[...] on this gives

{"company_txt" => "mac_id_1", "username_txtbx" => "mac_id_2"}

This is then given as the second element of the array for the outer map, resulting in

["signin", {"company_txt" => "mac_id_1", "username_txtbx" => "mac_id_2"}]

If you had a second top-level element of common_ids, it would result in the same processing. When the outer map call completes, you have

[["signin", {"company_txt" => "mac_id_1", "username_txtbx" => "mac_id_2"}], ...]

where the ... represents where additional top-level elements of common_ids would go.

Calling Hash[...] on this gives

{"signin" => {"company_txt" => "mac_id_1", "username_txtbx" => "mac_id_2"}, ...}

where the ... represents any additional top-level key-value pairs in the form k => v.

Hopefully that explanation helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM