有人可以帮我理解下面的代码吗?我一直在尝试添加'puts'来查看它的功能,但不断出现错误。这是我应该已经知道的练习/示例中的代码,但我不知道它在做什么。在我看来,我应该在方法之前定义一个items数组才有意义,但即便如此,我也无法理解它。
# search for `target_item` in `items`; return the array index
# where it first occurs
def find_item(items, target_item)
i = 0
while i < items.count
current_item = items[i]
if current_item == target_item
# found item; return its index; stop here and exit the
# method
return i
end
i += 1
end
# return nil to mean item not found
nil
end
答案 0 :(得分:1)
你需要一个数组items
来运行你的代码是正确的。您还需要变量target_item
的值。这两个变量作为参数传递给方法find_item
。如果方法在数组target_item
中找到items
的值,它将返回数组中该项的索引(第一个元素为0,第二个元素为1,依此类推);如果没有,它将返回nil
。
如果您在IRB中运行代码,它将返回=> :find_item
。这意味着它没有发现任何错误。但这并不意味着没有错误,因为代码运行时可能会出现错误。
让我们尝试一些数据。运行定义方法的代码(在IRB中)后,运行以下三行:
items = ['dog', 'cat', 'pig']
target_item = 'cat'
find_item(items, target_item) #=> 1
其中#=> 1
表示该方法返回1
,意味着它在target_items
的偏移1
处找到items
,这正是我们所期望的。
这相当于:
find_item(['dog', 'cat', 'pig'], 'cat')
另一方面,
find_item(items, 'bird') #=> nil
因为数组不包含'bird'
。两行
current_item = items[i]
if current_item == target_item
可以组合成一个:
if items[i] == target_item
但这不是重点,因为Rubiests不会以这种方式编写方法。相反,你通常会这样做:
def find_item(items, target_item)
items.each_with_index { |e,i| return i if e == target_item }
nil
end
[编辑:@Mark正确地指出了一种更简单的编写方法的方法。但是,我会坚持使用这个版本,因为我认为通过查看它的工作原理,你将学到一些有用的东西。]
内置的Ruby方法each_with_index
来自Enumgerable
模块,它始终可供您使用(以及该模块中定义的60多种其他方法)。引用方法时,最好包括定义它的类或模块。此方法为Enumerable#each_with_index。除此之外,如果你知道它的类或模块,它更容易找到该方法的文档。
虽然在Enumerable模块中定义了each_with_index
,但它是一个“枚举器”,这意味着它将items
中的值提供给下一个块,由{...}
表示(如此处所示) )或do ... end
。
在IRB中运行:
items = ['dog', 'cat', 'pig']
target_item = 'cat'
enum = items.each_with_index
#=> #<Enumerator: ["dog", "cat", "pig"]:each_with_index>
您可以将其转换为数组以查看它将为块提供的内容:
enum.to_a
#=> [["dog", 0], ["cat", 1], ["pig", 2]]
现在考虑将枚举数传递给块的第一个元素:
["dog", 0]
中的块变量
e
和i
items.each_with_index { |e,i| return i if e == target_item }
因此将被设置为:
e => "dog"
i => 0
因此,e == target_item
变为"dog" == "cat"
,即false
,因此return 0
不会被执行。但是,对于下一个项目,
e => "cat"
i => 1
由于"cat" == "cat"
为true
,return 1
已执行,我们已完成。如果items
不包含cat
,则枚举器将枚举所有项目,控件将转到以下语句nil
。由于这是最后执行的语句,该方法将返回nil
。
答案 1 :(得分:1)
此代码似乎是一个重写不佳的Array#index
。这是相同的:
items.index(target_item)