Ruby中嵌套哈希数组的输出处理及数据修改问题求助
Hey there! Let's work through these three tasks together—since you're a Ruby beginner, I'll break each step down clearly and point out common pitfalls that might be causing those "undefined method" errors you're seeing.
First, let's fix up your sample data to be valid Ruby (the unquoted stock symbols like GOOG would trigger a constant error otherwise):
companies = [ {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}}, {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}} ]
1. Output each company's name, ID, and stock symbol
The key here is accessing the nested hash values correctly. Since these are string-keyed hashes (not Ruby objects), you need to use bracket notation (["key"]) instead of dot syntax (like company.id). Here's how to do it:
companies.each do |company| # Pull values from the nested hashes id = company["id"] name = company["properties"]["name"] stock_symbol = company["properties"]["stock_symbol"] # Format and print the result puts "#{name} - #{id} - #{stock_symbol}" end
This will output:
Google - 1 - GOOG Facebook - 2 - FB
If you were getting "undefined method" errors here, it's likely because you tried using dot syntax (e.g., company.id) instead of company["id"].
2. Remove the "primary_role" key-value pair from all companies
You have two options here: modify the original array, or create a new array with the changes (safer if you want to keep the original data intact).
Option 1: Modify the original array
Use delete to remove the key directly from the properties hash:
companies.each do |company| company["properties"].delete("primary_role") end
Option 2: Create a new array (no changes to original data)
Use map to generate a new array, and reject to filter out the unwanted key (pure Ruby, no extra libraries needed):
updated_companies = companies.map do |company| # Make a copy of the company hash to avoid modifying the original new_company = company.dup # Create a new properties hash without "primary_role" new_company["properties"] = company["properties"].reject { |key, _value| key == "primary_role" } new_company end
3. Add an "industry" key-value pair to each company
Again, use bracket notation to add the new key to the properties hash. You can set a static value, or use logic to assign different industries based on the company name:
Static industry value for all companies
companies.each do |company| company["properties"]["industry"] = "Technology" end
Dynamic industry based on company name
companies.each do |company| industry = case company["properties"]["name"] when "Google" then "Internet & Software" when "Facebook" then "Social Media" else "Unknown" end company["properties"]["industry"] = industry end
Common mistakes to avoid
- Dot syntax vs bracket notation: Since these are plain hashes with string keys, always use
["key"]instead of.key(dot syntax works for symbol-keyed hashes or Ruby objects, not string-keyed hashes). - Modifying original data: If you don't want to change your original array, use
mapanddupto create copies of the hashes before making changes. - Nil errors: If some companies might not have a
propertieshash (unlikely with your API data), add a check likeif company["properties"]before accessing its keys to avoidNoMethodError: undefined method [] for nil:NilClass.
内容的提问来源于stack exchange,提问作者J. Ballard

