【问题标题】:search for `target_item` in `items`; return the array index在“items”中搜索“target_item”;返回数组索引
【发布时间】:2014-06-13 09:50:03
【问题描述】:

谁能帮我理解下面的代码?我一直在尝试添加“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

【问题讨论】:

  • 该死的,好吧,我刚收到!我完全糊涂了,这对我来说非常先进。不过谢谢!

标签: ruby arrays while-loop


【解决方案1】:

关于需要一个数组items 来运行您的代码是正确的。您还需要变量target_item 的值。这两个变量作为参数传递给方法find_item。如果该方法在数组items 中找到target_item 的值,它将返回该项目在数组中的索引(第一个元素为0,第二个元素为1,依此类推);如果没有,它将返回nil

如果您在 IRB 中运行代码,它将返回 =&gt; :find_item。这意味着它没有发现任何错误。然而,这并不意味着没有错误,因为在运行代码时可能会出现错误。

让我们用一些数据来试试吧。运行定义方法的代码(在 IRB 中)后,运行以下三行:

items = ['dog', 'cat', 'pig']
target_item = 'cat'
find_item(items, target_item) #=> 1

其中#=&gt; 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]

块变量,ei 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"truereturn 1 被执行,我们就完成了。如果items 不包含cat,则枚举器将枚举所有项目并且控制将转到以下语句nil。由于这是执行的最后一条语句,该方法将返回 nil

【讨论】:

    【解决方案2】:

    这段代码似乎是重写得很糟糕的Array#index。这是相同的:

    items.index(target_item)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多