Ruby中else和elsif的区别

Ruby中else和elsif的区别,ruby,Ruby,在此代码中,如果我将我的名字bobby li传递给最长的单词,它将返回bobby。但如果我选择elsif而不是elsif,它将返回li。有人能解释一下吗 def longest_word(sentence) words = sentence.split(" ") longest_word = nil word_idx = 0 while word_idx < words.length current_word = words[word_idx] if l

在此代码中,如果我将我的名字bobby li传递给最长的单词,它将返回bobby。但如果我选择elsif而不是elsif,它将返回li。有人能解释一下吗

def longest_word(sentence)
  words = sentence.split(" ")
  longest_word = nil
  word_idx = 0

  while word_idx < words.length
    current_word = words[word_idx]

    if longest_word == nil
      longest_word = current_word
    elsif longest_word.length < current_word.length
      longest_word = current_word
    end

    word_idx += 1
 end

 return longest_word
end

在第一次迭代期间,最长的_字为nil,因此将执行if条件。如果使用else,在循环的剩余迭代中,If条件将永远不会计算为true,因为它不再为nil

因此,无论当前单词的长度是否大于最长单词,它都会将当前单词更新为最长单词。因此,如果使用elsif而不是elsif,则始终会将最后一个单词作为最长的单词。

如果使用elsif,则始终会检查当前单词长度是否大于迄今为止找到的最长单词,并且仅当条件的计算结果为真时才更新最长的单词,即当前单词确实比最长的单词长。所以答案是鲍比


但是如果您使用else,那么我们只会将最长的单词更新为当前单词,而不管当前单词是否比最长的单词长。所以,ans是单词[last_index],即li

这并不是你真正想要的,但我希望它能有所帮助

我突然想到,你在你的工作中做了很多不必要的工作。下面是几个可能的替代方案

第一种方法:保留迭代器 在这里,使用句子.split.每个do | current | u word |都可以让你跳过所有你正在做的idx事情

现在,在你的代码中,你说:

  if longest_word == nil
    longest_word = current_word
    ...
  end
我建议您使用:

  if longest_word.nil?
    longest_word = current_word
    ...
  end
  
或者更好:

  unless longest_word
    longest_word = current_word
    ...
  end
如果再往前走一步,您可以通过使用尾随条件来摆脱第一条If语句:

  longest_word = current_word unless longest_word
  longest_word = current_word if current_word.length > longest_word.length
ruby IMO中更惯用的说法是:

  longest_word ||= current_word
谷歌“ruby条件赋值”获取| |=的详细信息

在那之后,你可以说:

  if current_word.length > longest_word.length
    longest_word = current_word
  end
但我认为使用尾随条件更为简洁:

  longest_word = current_word unless longest_word
  longest_word = current_word if current_word.length > longest_word.length
这种方法为您节省了七行代码——这看起来可能并不多。但是,随着时间的推移,它会堆积起来。更重要的是,我认为它可能更容易阅读和理解

第二种方法:放弃迭代器 你可以简单地说:

def longest_word(sentence)
  sentence.split(" ")
          .sort{|x,y| x.length <=> y.length}
          .last
end
这基本上是说,按照长度的升序对单词数组进行排序,然后返回最后一个元素

就我个人而言,我会这样写:

def longest_word(sentence)
  sentence.split(" ").sort{|x,y| x.length <=> y.length}.last
end
您保存了我喜欢的12行代码,这样我就可以一次在屏幕上看到更多内容,而不必滚动代码

没有条件。没有作业。没有循环。只是干净易读


无论如何,我希望这能有所帮助。

区别在于其他人不接受条件。所以在这种情况下,你的长度检查就被忽略了。@SergioTulentsev:好吧,它仍然被评估,但它不是一个条件。它被解释为else子句主体的另一部分。因为它没有任何副作用,并且它的返回值被忽略,所以它什么都不做,所以在某种意义上它被忽略了。