rubyhashmapiterationeacharrayiterator

how can I iterate through this array of hashes to receive a particular value : RUBY


the hash I have is the following:

aoh=[
  { "name": "Vesper",
    "glass": "martini",
    "category": "Before Dinner Cocktail",
    "ingredients": [
      { "unit": "cl",
        "amount": 6,
        "ingredient": "Gin" },
      { "unit": "cl",
        "amount": 1.5,
        "ingredient": "Vodka" },
      { "unit": "cl",
        "amount": 0.75,
        "ingredient": "Lillet Blonde" }
    ],
    "garnish": "Lemon twist",
    "preparation": "Shake and strain into a chilled cocktail glass." },
  { "name": "Bacardi",
    "glass": "martini",
    "category": "Before Dinner Cocktail",
    "ingredients": [
      { "unit": "cl",
        "amount": 4.5,
        "ingredient": "White rum",
        "label": "Bacardi White Rum" },
      { "unit": "cl",
        "amount": 2,
        "ingredient": "Lime juice" },
      { "unit": "cl",
        "amount": 1,
        "ingredient": "Syrup",
        "label": "Grenadine" }
    ],
    "preparation": "Shake with ice cubes. Strain into chilled cocktail glass." }]

How can I iterate through this to get JUST the ingredient (without returning name,glass,category,etc.)? I also need the same iteration for amount but I assume that will look just like the iteration for ingredient. Sorry for the dumb question, I'm new to ruby and have attempted this for hours now.


Solution

  • You have an array of two elements in your example. Those two elements are hashes with key/value pairs. You can loop through the array with the #each method and access the values that the :"ingredients" keys store like this:

    aoh.each do |hash|
      hash[:ingredients]
    end
    

    The :ingredients keys each store another array of hashes. An example hash is:

    { "unit": "cl",
            "amount": 6,
            "ingredient": "Gin" }
    

    You can then access the value under the :ingredient key by doing hash[:ingredient]. The final result looks something like this:

       aoh.each do |array_element|
        array_element[:ingredients].each do |ingredient|
          ingredient[:ingredient]
        end
      end
    

    This currently only iterates through the arrays and hashes. If you want to also print the result you can do this:

      aoh.each do |array_element|
        array_element[:ingredients].each do |ingredient|
          puts ingredient[:ingredient]
        end
      end
    #=> Gin
    #   Vodka
    #   Lillet Blonde
    #   White rum
    #   Lime juice
    #   Syrup
    

    If you want to get a modified array, you can use #map (or #flat_map). You can also get the amount with the value like this:

       aoh.flat_map do |array_element|
        array_element[:ingredients].map do |ingredient|
          [[ingredient[:ingredient], ingredient[:amount]]
        end
      end
    #=> [["Gin", 6], ["Vodka", 1.5], ["Lillet Blonde", 0.75], ["White rum", 4.5], ["Lime juice", 2], ["Syrup", 1]]