在循环外打印时,“未定义的局部变量”

时间:2017-09-03 00:24:50

标签: ruby

我是Ruby的新手并且学习基础知识。我试图弄清楚数组中的最大值,该值在数组中的位置并将其打印出来。我遇到了一个奇怪的问题,我希望有人可以帮忙解释一下。

这是我的代码:

highest_grocery = 0
#This loop will iterate over all the grocery expenditures to find the maximum
expenses["groceries"].length.times do |i|
  if highest_grocery < expenses["groceries"][i]
    highest_grocery = expenses["groceries"][i]
    friend_num_grocery = i + 1
  end

end
print "Friend #{friend_num_grocery} paid the most for groceries. With a total grocery bill of: $#{highest_grocery}"

当我运行此操作时,出现错误undefined local variable or method friend_num_grocery for main:Object

我挣扎了一段时间,但我偶然发现如果我之前创建了friend_num_grocery变量,它会正常工作,如下所示:

highest_grocery = 0
friend_num_grocery = 0
#This loop will iterate over all the grocery expenditures to find the maximum
expenses["groceries"].length.times do |i|
  if highest_grocery < expenses["groceries"][i]
    highest_grocery = expenses["groceries"][i]
    friend_num_grocery = i + 1
  end

end
print "Friend #{friend_num_grocery} paid the most for groceries. With a total grocery bill of: $#{highest_grocery}"

有谁知道为什么第一个不起作用,但第二个没有?谢谢!

1 个答案:

答案 0 :(得分:1)

在第一个片段中,变量friend_num_grocery在提供给#times方法的块中定义,因此只能在块本身内访问(即此变量范围是块)。

在外部作用域中定义变量(就像在第二个代码片段中一样)是一种解决这个问题的方法,但更像Ruby的方式是依赖于返回你提供的方法阻止。

另请注意,Ruby提供了迭代集合的工具,而无需明确索引集合元素。

实现预期结果的一种可能的替代方案是

groceries = Array.new(10) { rand(100) } # build an array with random values
p groceries

highest_grocery, friend_num_grocery = groceries.each_with_index
                                               .sort { |a, b| a.first <=> b.first }
                                               .last

puts "Friend #{friend_num_grocery + 1} paid the most for groceries. With a total grocery bill of: $#{highest_grocery}"

其中

  • #each_with_index:为我们提供了一个包含值和索引的数据结构(数组数组)(如[[15, 0], [2, 1], ..., [13, 9]]),因此我们可以根据值进行排序,并在输出中接收值和索引。
  • #sort:根据第一个元素的值对数组进行排序(但返回完整的数组)。
  • #last:选择最后一个数组,这是最有价值的数组。
  • highest_grocery&amp; friend_num_grocery是通过数组匹配分配的(例如a, b = [1, 2]a = 1b = 2}。

运行此代码几次

$ ruby a.rb                                                                                                                                                           
[39, 67, 26, 75, 19, 28, 91, 40, 7, 42]
Friend 7 paid the most for groceries. With a total grocery bill of: $91
$ ruby a.rb 
[27, 21, 45, 34, 49, 77, 16, 54, 87, 12]
Friend 9 paid the most for groceries. With a total grocery bill of: $87
$ ruby a.rb 
[51, 70, 22, 25, 85, 4, 31, 64, 65, 6]
Friend 5 paid the most for groceries. With a total grocery bill of: $85
$ ruby a.rb 
[82, 17, 22, 28, 74, 70, 13, 37, 60, 68]
Friend 1 paid the most for groceries. With a total grocery bill of: $82
$ ruby a.rb 
[46, 6, 35, 60, 95, 36, 81, 27, 70, 78]
Friend 5 paid the most for groceries. With a total grocery bill of: $95

值得注意的是:

  • #each_with_index&amp; #sortEnumerable模块的成员。熟悉它可能有助于编写有效的Ruby代码
  • 当存在相同的杂货值时,我建议的代码可能不会出现预期的行为
  • 初始化a = 0h = {}等变量并不是优雅的Ruby代码