使用.each ruby​​替换变量

时间:2018-01-24 10:16:41

标签: ruby

我是Ruby的初学者,并且在弄清楚为什么我无法修改位于块外的初始化变量时遇到了一些麻烦。例如,我想做以下(但没有for循环,因为我听说在Ruby中使用它会导致一些讨厌的错误):

sentence = "short longest"

def longest_word(sentence)
  max_length = 0
  for word in sentence.split(" ")
    if word.length > max_length
      max_length = word.length
      max_word = word
    end
  end
  return max_word
end

我尝试了什么:

def longest_word(sentence)
    max_length = 0
    sentence.split(" ").each do |word|
        if word.length > max_length
            max_length = word.length
            max_word = word
        end
    end
    return max_word
end

我知道你可以使用这样的东西:

def longest_word(sentence)

     return sentence.split(" ").each.map {|word| [word.length, word]}.max[1]
end

同样想了解为什么我不能像执行for循环方法一样执行.each方法。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:5)

首先,请注意,最简单的方法是:

sentence.split(" ").max_by(&:length)

您的方法,可以略微简化为:

sentence.split(" ").map {|word| [word.length, word]}.max[1]

也有效,但更加混乱。

Array comparison以“元素方式”的方式工作。例如,[2, "foo"] > [1, "bar"]因为2 > 1。这就是max在这种情况下工作的原因:因为你实际上间接地比较了每个数组的第一个元素。

  

为什么我不能像执行for循环方法那样使用.each方法?

因为块中定义的变量只能在该块中访问。

这是几乎所有语言中非常常见的编程原则,称为scope of the variable

def longest_word(sentence)
  max_length = 0
  sentence.split(" ").each do |word|
    if word.length > max_length
      max_length = word.length
      max_word = word  # <--- The variable is defined IN A BLOCK (scope) here
    end
  end
  return max_word      # <--- So the variable does not exist out here
end

一个简单的解决方法(但正如我上面提到的,这不是我推荐的实际解决方案!)是在块外部初始化变量:

def longest_word(sentence)
  max_length = 0
  max_word = nil   # <--- The variable is defined OUTSIDE THE BLOCK (scope) here
  sentence.split(" ").each do |word|
    if word.length > max_length
      max_length = word.length
      max_word = word
    end
  end
  return max_word  # <--- So the variable exists here
end