带有弦的红宝石中的意外类型转换



我正在尝试解决一个挑战,您要插入一串单词,但要返回字符串中最长的单词。我的策略是将字符串分解为单个单词数组并搜索数组。但是,我遇到了类型的转换错误。是什么导致类型转换错误?这对我来说特别奇怪,因为我实际上没有看到这里发生任何类型的转换。

def LongestWord(sen)
  sen1 = sen.split("/W+/")
  grt = 0
  sen1.each do |i|
      if sen1[i].length > sen1[grt].length # Type conversion error
          grt = i
      end
  end
  sen1[grt] 
end
# keep this function call here    
puts LongestWord(STDIN.gets)  

类型转换是由数组条目i转换为(可能失败的)变成整数引起的(尽管我想我想可能是Ruby试图将数组转换为Hash,并使用i作为哈希的钥匙)。

您的误解是,您认为您将数组的索引传递到each的块中。传递给该块的是数组中的每个单个值。即,如果您的字符串sen是"这是一个愚蠢的字符串",则传递的值是'this','is','a','',silly'和'string'。

您会得到错误,因为当代码运行时,isen1的第一个值,这导致评估sen1['some string']

一个数组不能具有字符串索引,只有hash可以,导致类型错误。

冥想:

def longest_word(sen)
  sen1 = sen.split # => ["foo", "barbaz"]
  grt = 0
  sen1.each do |i|
    i # => "foo"
    sen1 # => ["foo", "barbaz"]
    sen1[i] # => 
    sen1[grt] # => 
    sen1[i].length # => 
    sen1[grt].length # => 
    if sen1[i].length > sen1[grt].length #Type conversion error
      grt = i # => 
    end
  end

  sen1[grt] 
end
# keep this function call here    
longest_word('foo barbaz')

进一步分解,这是有问题的问题:

sen1 = 'foo barbaz'.split
sen1['foo'] # => 
# ~> TypeError
# ~> no implicit conversion of String into Integer

您看不到类型转换,但它在那里。在一个以上的地方。

AS Derrell Durrett 在他的答案中指出,您(错误地)假设数组的索引传递给了块,而不是其元素。

然后您编写if sen1[i].length > sen1[grt].length。让我们考虑一下字符串是'这是一个愚蠢的字符串'。第一个元素是'this',您要做的是if sen1['this'].length > sen1[0].length。由于Ruby数组始终具有整数索引,Ruby试图将"此"转换为整数,以便在指定位置找到元素。当然,这失败了!

,但是您的代码离正确不远。一些小的更改,它的运行良好:

def longest_word(sen)
  sen1 = sen.split(" ")
  grt = 0
  sen1.each_index do |i|
    if sen1[i].length > sen1[grt].length 
      grt = i
    end
  end
  sen1[grt] 
end
puts LongestWord(STDIN.gets)  

现在您将通过sen1.each_index传递索引,并且工作正常。

请注意,我将您的方法的名称更改为 longest_word 。实际上,这要好得多,因为第一个大写字母保留给常数和班级名称。

我也想指出您不使用良好的红宝石风格。这可以像这样写:

def longest_word(str)
  str.split(" ").max_by{ |s| s.length }
end

结果将相同。

最新更新