从哈希数组中搜索并拉出结果

时间:2014-08-07 01:05:33

标签: ruby arrays conditional-statements hash

我正在进行一项练习,我有两个杂货店杂项阵列。我正在提示用户"您正在寻找什么食品?"我正在尝试接受用户的回答,并确定:

如果 - 他们的反应是哈希#1的阵列,做一些事情 埃尔西夫 - 他们的回应是哈希#2,做点什么 别的 - 做点什么

我无法让它发挥作用。无论我输入什么用户输入,我都会收到第一个 if 语句的响应,"我在购物清单上找到了您的商品。"

以下是哈希,数组和代码(不起作用):

milk    = {:item => "milk",    :aisle => 15, :price => 3.29}
grapes  = {:item => "grapes",  :aisle => 1,  :price => 7.99}
eggs    = {:item => "eggs",    :aisle => 12, :price => 1.95}  
peanuts = {:item => "peanuts", :aisle => 17, :price => 5.98} 


grocery_list = [milk, grapes, eggs]
grocery_cart = [peanuts]  



def is_item_on_grocery_list?(list)
  list.each do |food|
    food[:item] == @choice
  end
end

def is_item_on_grocery_cart?(cart)
  cart.each do |food|
    food[:item] == @choice
  end
end


puts "Type an item from your Grocery List to find out what aisle it is on: "
print "> "
@choice = $stdin.gets.chomp.downcase.strip


if is_item_on_grocery_list?(grocery_list)
  puts "I found your item on the grocery list."
elsif is_item_on_grocery_cart?(grocery_cart)
  puts "Your item is already in your cart."
else puts "Your item is not on either list."
end 

谢谢。

1 个答案:

答案 0 :(得分:0)

Justin,是的,用each替换any?修复了问题,但是您应该知道的代码还有一些其他问题。

首先,您的两种方法在功能上是相同的。是的,你给了方法和块变量不同的名字,但它们做同样的事情。您可以通过调用其中任何一个,一次传递参数grocery_list并使用参数grocery_cart调用一次来确认。

其次,您可以通过将is_item_on_grocery_list?的值作为参数传递而不是将其硬连接来使您的方法@choice更具通用性。因此,请考虑将其写为:

milk    = {:item => "milk",    :aisle => 15, :price => 3.29}
grapes  = {:item => "grapes",  :aisle => 1,  :price => 7.99}
eggs    = {:item => "eggs",    :aisle => 12, :price => 1.95}  
peanuts = {:item => "peanuts", :aisle => 17, :price => 5.98} 

grocery_list = [milk, grapes, eggs]
grocery_cart = [peanuts]

def item_present?(arr, item)
  arr.any? do |food|
    food[:item] == item
  end
end

puts "Type an item from your Grocery List to find out what aisle it is on: "
print "> "
choice = gets.chomp.downcase.strip

if item_present?(grocery_list, choice)
  puts "I found your item on the grocery list."
elsif item_present?(grocery_cart, choice)
  puts "Your item is already in your cart."
else puts "Your item is not on either list."
end 

假设用户输入" eggs"。这会打印出来,"我在购物清单上找到了你的物品。",这很好,但是假设你也想告诉那个人有过egges的过道。你可以这样做的一种方法是将item_present?更改为:

def item_present?(arr, item)
  arr.any? do |food|
    (food[:item] == item) ? food[:aisle] : false
  end
end

也就是说,它不会返回truefalse,而是返回过道(这是一个真值)或false。然而,这相当混乱,因此可以考虑使用不同的数据结构。这是一种可能性:

food = { "milk"    => { :loc => :list, :aisle => 15, :price => 3.29},
         "grapes"  => { :loc => :list, :aisle => 1,  :price => 7.99},
         "eggs"    => { :loc => :list, :aisle => 12, :price => 1.95},
         "peanuts" => { :loc => :cart, :aisle => 17, :price => 5.98}
       } 

def item_present?(food, type, item)
  food.any? { |f| food.key?(item) && food[item][:loc] == type }
end

puts "Type an item from your Grocery List to find out what aisle it is on: "
print "> "
choice = gets.chomp.downcase.strip

if item_present?(food, :list, choice)
  puts "I found your item on the grocery list. Try aisle #{food[choice][:aisle]}"
elsif item_present?(food, :cart, choice)
  puts "Your item is already in your cart.  Are you blind?"
else puts "Your item is not on your list or in your cart."
end

现在,如果用户输入" eggs",则会打印以下内容:

"I found your item on the grocery list. Try aisle 12"