learning_to_swim
learning_to_swim

Reputation: 361

Pulling out Keys and Values from an hash of arrays

I have an hash like this -

    {"examples"=>
      [{"year"=>1999,
            "provider"=>{"name"=>"abc", "id"=>711},
            "url"=> "http://example.com/1",
            "reference"=>"abc",
            "text"=> "Sample text 1",
            "title"=> "Sample Title 1",
            "documentId"=>30091286,
            "exampleId"=>786652043,
            "rating"=>357.08115},
        {"year"=>1999,
            "provider"=>{"name"=>"abc", "id"=>3243},
            "url"=> "http://example.com/2",
            "reference"=>"dec",
            "text"=> "Sample text 2",
            "title"=> "Sample Title 2",
            "documentId"=>30091286,
            "exampleId"=>786652043,
        "rating"=>357.08115},
        {"year"=>1999,
            "provider"=>{"name"=>"abc", "id"=>191920},
            "url"=> "http://example.com/3",
            "reference"=>"wer",
            "text"=> "Sample text 3",
            "title"=> "Sample Title 3",
            "documentId"=>30091286,
            "exampleId"=>786652043,
        "rating"=>357.08115}]
}

and I would like to create a new array by pulling out the keys, and values for just the "text", "url" and "title" keys like below.

   [
     {"text"=> "Sample text 1", "title"=> "Sample Title 1", "url"=> "http://example.com/1"},
     {"text"=> "Sample text 2", "title"=> "Sample Title 2", "url"=> "http://example.com/2"},
     {"text"=> "Sample text 3", "title"=> "Sample Title 3", "url"=> "http://example.com/3"}
   ]

Any help is sincerely appreciated.

Upvotes: 1

Views: 605

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110755

Here's another way this could be done (where h is the hash given in the question).

KEEPERS = ['text','url','title']

h.each_key.with_object({}) { |k,g|
  g[k] = h[k].map { |h| h.select { |sk,_| KEEPERS.include? sk } } }
    #=> {"examples"=>[
    #     [{"url"=>"http://example.com/1", "text"=>"Sample text 1",
    #       "title"=>"Sample Title 1"},
    #      {"url"=>"http://example.com/2", "text"=>"Sample text 2",
    #       "title"=>"Sample Title 2"},
    #      {"url"=>"http://example.com/3", "text"=>"Sample text 3",
    #       "title"=>"Sample Title 3"}]}

Here we simply create a new hash (denoted by the outer block variable g) which has all the keys of the original hash h (just one, "examples", but there could be more), and for each associated value, which is an array of hashes, we use Enumerable#map and Hash#select to retain only the desired key/value pairs from each of those hashes.

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118299

You should do as

hash['examples'].map do |hash|
    keys = ["text", "title", "url"]
    keys.zip(hash.values_at(*keys)).to_h
end

If you are below < 2.1 use,

 Hash[keys.zip(hash.values_at(*keys))]

Upvotes: 7

Related Questions