关于需要一个数组items 来运行您的代码是正确的。您还需要变量target_item 的值。这两个变量作为参数传递给方法find_item。如果该方法在数组items 中找到target_item 的值,它将返回该项目在数组中的索引(第一个元素为0,第二个元素为1,依此类推);如果没有,它将返回nil。
如果您在 IRB 中运行代码,它将返回 => :find_item。这意味着它没有发现任何错误。然而,这并不意味着没有错误,因为在运行代码时可能会出现错误。
让我们用一些数据来试试吧。运行定义方法的代码(在 IRB 中)后,运行以下三行:
items = ['dog', 'cat', 'pig']
target_item = 'cat'
find_item(items, target_item) #=> 1
其中#=> 1 表示该方法返回了1,这意味着它在items 中的偏移量1 处找到了target_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。除此之外,如果您知道其来源的类或模块,则更容易找到该方法的文档。
虽然each_with_index 是在 Enumerable 模块中定义的,但它是一个“枚举器”,这意味着它将来自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 in
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。