【问题标题】:Understanding strange output in multidimensional array了解多维数组中的奇怪输出
【发布时间】:2014-08-25 00:01:09
【问题描述】:

我是 ruby​​ 新手,我试图迭代一个二维数组。我在我的代码中犯了一个错误。从那个错误中,我注意到了一些意想不到的输出。

s = [["ham", "swiss"], ["turkey", "cheddar"], ["roast beef", "gruyere"]]
i = 0;
s.each{
    |array| so = array[i] # pin
    puts so[i]
    }

由于#pin,如果i = 0,则输出为h t r。 i = 1 给出 w hr。 i > 1 给出错误:

C:/Ruby.rb in `block in <main>': undefined method `[]' for nil:NilClass (NoMethodError)
    from C:/Ruby.rb:3:in `each'
    from C:/Ruby.rb:3:in `<main>'

如果我使用|array| so = array # pin,那么我的代码不会产生奇怪的输出。我将修复剩余的内容,以使我的代码迭代 'i' 可以具有的所有值。

请解释一下。

PS:工作代码在这里

s = [["ham", "swiss"], ["turkey", "cheddar"], ["roast beef", "gruyere"]]
s.each{
  |array| so = array
  array.each{
  |str| puts str   
  }
}

【问题讨论】:

  • 您看到的是获取超出范围的数组值的结果。使用 array.fetch(i) 你会得到一个更有帮助的错误。我通常使用 fetch 进行数组和哈希查找,这样你就不会感到奇怪 x 在 nil:NilClass 上被调用了
  • @Joeyjoejoejr - 谢谢。但是作为一个初学者,我很困惑为什么 ruby​​ 会这样。
  • 这里的人怎么这么讨厌? -1 是什么原因,原因在哪里?如果您认为某个问题质量很差并且必须删除,那么我很乐意遵守。但是,我首先需要一个理由。

标签: ruby arrays multidimensional-array


【解决方案1】:

对于每种三明治,当 i 为 0 时,第一个元素也为 0,即肉。所以[0] 是肉的第一个字母。

当 i 为 1 时,即为第二个元素,即为奶酪。所以[1] 是奶酪的第二个字母。

当 i 为 3 时,三明治没有第三部分。 nil 也是如此。所以[2] 要求 nil[2]。

nil 是一个类,就像 ruby​​ 中的所有内容一样。但是 nil 没有像数组和其他实现 Enumerable 模块的类那样实现 [] 方法。

由于 nil 不支持 [] 方法,所以会出现未定义方法错误。

即使是其他语言中内置的操作,如 +、[] 和 ==,也是可以在 Ruby 中覆盖的方法。

要准确了解发生了什么,请尝试以下代码:

class NilClass
  def [] (i)
    nil
  end
end

执行将打开现有的 NilClass,并添加一个名为 [] 的方法。然后你可以做 nil[1] ,它会返回 nil。像这样更改现有类在 Ruby 世界中称为 monkey patching

【讨论】:

    【解决方案2】:

    当您请求so[2] 时,您实际上是在请求第三个元素,如果它不存在,您将收到错误消息。

    我建议像这样构建你的块:

    s.each do |pair|
      puts pair
    end
    

    注意do/end 而不是{} 以及与each 内联的迭代变量的放置。另请注意,这相当于您的“工作代码”,因此在这种情况下您不需要额外的迭代器。

    【讨论】:

      猜你喜欢
      • 2020-01-27
      • 1970-01-01
      • 2015-03-18
      • 2023-04-06
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      相关资源
      最近更新 更多