0

I have an array of hashes of hashes. Here is what the structure looks like:

items = [{"Spaghetti & Meatballs"=>
   {
    :menu_item_name=>"Spaghetti & Meatballs",
    :quantity=>192,
    :category=>"delicious"}},
 {"Bananas"=>
   {
    :menu_item_name=>"Bananas",
    :quantity=>187,
    :category=>"sweet"}}]

I want to do the following:

items["Bananas"] 

and return the hash at bananas.

sawa
  • 165,429
  • 45
  • 277
  • 381
tnaught
  • 301
  • 4
  • 13
  • you don't need the array, you can have `items = { "Bananas" => { menu_item_name: "Bananas", quantity: 187 }, "Spaghetti" => { menu_item_name: "Spaghetti", quantity: 192 } }` – max pleaner Oct 04 '17 at 17:52
  • This is how my data is sent to me, its in an array. I cannot change this. – tnaught Oct 04 '17 at 17:53
  • 1
    @SebastianPalma, why is this question a duplicate? This question is not how to obtain a particular hash from an array of hashes (the subject of the linked question); it is how to make `items["Bananas"]` do that. (I just voted to reopen, and presto, it reopened. I didn't know I possessed magic dust.) – Cary Swoveland Apr 02 '19 at 17:20

2 Answers2

1

With:

items = [{"Spaghetti & Meatballs"=>
   {
    :menu_item_name=>"Spaghetti & Meatballs",
    :quantity=>192,
    :category=>"delicious"}},
 {"Bananas"=>
   {
    :menu_item_name=>"Bananas",
    :quantity=>187,
    :category=>"sweet"}}]     

Try:

items.find{|hsh| hsh.keys.first == "Bananas"}

In console:

2.3.1 :011 > items.find{|hsh| hsh.keys.first == "Bananas"}
 => {"Bananas"=>{:menu_item_name=>"Bananas", :quantity=>187, :category=>"sweet"}} 

If you want, you could assign it to a variable:

bananas_hsh = items.find{|hsh| hsh.keys.first == "Bananas"}

Again, in console:

2.3.1 :012 > bananas_hsh = items.find{|hsh| hsh.keys.first == "Bananas"}
 => {"Bananas"=>{:menu_item_name=>"Bananas", :quantity=>187, :category=>"sweet"}} 
2.3.1 :013 > bananas_hsh
 => {"Bananas"=>{:menu_item_name=>"Bananas", :quantity=>187, :category=>"sweet"}} 
jvillian
  • 19,953
  • 5
  • 31
  • 44
1

You would like items["Banana"] to return an array of elements (hashes) of items that have a key "Bananas". Let's consider how that would be done.

Since items.class #=> Array we would have to define an instance method Array#[] to do that. There's a problem, however: Array already has the instance method Array#[], which is used like so: [1,2,3][1] #=> 2, where the argument is the index of the array whose value is to be returned.

With the proviso that the hash's keys are not numeric, we could do the following.

class Array
  alias :left_right_paren :[]
  def [](x)
    if x.is_a?(Integer)
      left_right_paren(x)
    else
      find { |h| h.keys.include?(x) }
    end
  end
end

[1,2,3][1]
   #=> 2
items["Bananas"]
   #=> {"Bananas"=>{:menu_item_name=>"Bananas", :quantity=>187, :category=>"sweet"}}

All that remains is to decide whether this would be a good idea. My opinion? YUK!!

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100