You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby哈希数组单个键遍历方法及食谱份数转换器代码报错求助

Recipe Converter Fixes & Optimizations

Hey there! Let's work through your recipe converter problems step by step—first optimizing your input code, then fixing that portion conversion error, and finally clarifying how to work with your array of hashes in Ruby.

1. Optimizing the Ingredient Input Code

Your current input code works, but we can make it cleaner, more robust, and ready for the math later on. Here are the key improvements:

  • Remove unused defaults: Your quantity = 1, metric = "g", and ingredient = "default" aren't actually used since you overwrite them with user input.
  • Convert quantity to a number: Right now you're storing quantity as a string, which will break math operations later. We'll convert it to a Float (to handle fractions like 2.5) or Integer.
  • Simplify loop logic: Make prompts clearer and avoid repeating the "press X" instruction.
  • Add basic input validation: Ensure the user enters a valid number for quantity.
  • Simplify ingredient creation: You don't need a separate method—you can create the hash directly when pushing to the array.

Here's the optimized version:

puts "Please enter your recipe ingredients. Press X when done.\n"

recipe = []

loop do
  puts "Enter ingredient name (or X to finish):"
  ingredient = gets.chomp.capitalize
  break if ingredient == "X"

  puts "Enter unit (e.g., g, oz, cup):"
  metric = gets.chomp.downcase

  # Validate quantity input
  quantity = nil
  until quantity
    puts "Enter quantity (e.g., 500, 2.5):"
    input = gets.chomp
    # Try converting to float first, fall back to integer
    quantity = Float(input) rescue Integer(input) rescue nil
    puts "Please enter a valid number!" unless quantity
  end

  recipe << { quantity: quantity, metric: metric, ingredient: ingredient }
end

puts "\nYour recipe ingredients:"
recipe.each { |ing| puts "#{ing[:quantity]} #{ing[:metric]} #{ing[:ingredient]}" }

2. Fixing the Portion Conversion Error

The main error you're seeing (undefined local variable or method orig_portion'`) happens because Ruby methods have their own scope—they can't access variables defined in the main program unless you pass them as arguments. Let's fix this, plus other syntax and logic issues:

First, Fix the Portion Input Code

Your current portion input has syntax errors (extra end statements) and incorrect validation. Here's the corrected version:

# Get original portion size with validation
orig_portion = nil
until orig_portion
  puts "\nHow many portions is this recipe for?"
  input = gets.chomp
  orig_portion = Integer(input) rescue nil
  puts "Please enter a valid whole number!" unless orig_portion
end

# Get new portion size with validation
new_portion = nil
until new_portion
  puts "How many people are you cooking for?"
  input = gets.chomp
  new_portion = Integer(input) rescue nil
  puts "Please enter a valid whole number!" unless new_portion
end

Then, Fix the convert_recipe Method

We need to pass orig_portion and new_portion as arguments to the method. Also, your loop was trying to iterate over key, value (which is for hashes), but recipe is an array of hashes—so we iterate over each hash in the array instead. Finally, use the correct symbol keys to access hash values:

def convert_recipe(recipe, orig_portion, new_portion)
  conversion_factor = new_portion.to_f / orig_portion.to_f
  recipe.each do |ingredient_hash|
    updated_quantity = ingredient_hash[:quantity] * conversion_factor
    # Round to 2 decimal places for readability (adjust as needed)
    rounded_quantity = sprintf("%.2f", updated_quantity).to_f
    # Remove .0 if it's a whole number
    rounded_quantity = rounded_quantity.to_i if rounded_quantity == rounded_quantity.to_i
    puts "#{rounded_quantity} #{ingredient_hash[:metric]} #{ingredient_hash[:ingredient]}"
  end
end

# Run the conversion
puts "\nConverted recipe for #{new_portion} portions:"
convert_recipe(recipe, orig_portion, new_portion)

3. How to Iterate Over an Array of Hashes in Ruby

To clarify: Your recipe variable is an array where each element is a hash. When you loop through it:

  • Use recipe.each do |ingredient_hash| to grab each individual hash from the array.
  • Access values inside the hash using the symbol keys you defined (e.g., ingredient_hash[:quantity], ingredient_hash[:metric]).

For example, if you just wanted to print all ingredient names:

recipe.each do |ing|
  puts ing[:ingredient]
end

If you wanted to collect all quantities into a separate array:

quantities = recipe.map { |ing| ing[:quantity] }
puts quantities.inspect

Putting It All Together

Combine the optimized input code, portion input code, and conversion method, and your recipe converter will work smoothly—handling input validation, correct type conversions, and portion scaling without errors.

内容的提问来源于stack exchange,提问作者Siobhan Vida Ashmole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:17:32