Ruby for 循环中的数据类型转换错误
Datatype conversion error in Ruby for-loop
我正在寻求一些帮助来理解为什么在尝试使用 for 循环搜索字母数组(并将它们添加到结果字符串中)时出现错误(没有将 nil 隐式转换为字符串) ,这似乎是真正的问题),但当我出于相同目的使用 while 循环或 'each' 时却不是。我查看了很多文档,但无法找到为什么会发生这种情况的答案。我知道我可以只使用 "each" 方法并收工,但我更愿意理解原因和结果(并希望将来避免这个问题)。
下面的方法可以正常工作:打印 "result" 这是原始字符串,只有 "!"代替任何元音。
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
string_array.each do |i|
if vowels.include?(i)
result+="!"
else
result+=i
end
end
puts result
但是,我最初的尝试(在下面发布)引发了上述错误:"no implicit conversion of nil into String" 引用第 5 行和第 9 行。
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
for i in 0..string_array.length
if vowels.include?(string_array[i])
result+= "!"
else
result+=string_array[i]
end
end
puts result
通过实验,我设法让它工作了;我确定——通过打印到屏幕而不是存储在 "result" 中——问题发生在目标字母与字符串 "result" 的连接过程中。但为什么 "string_array[i]" (第 9 行)被视为 NIL 而不是字符串?我觉得我错过了一些非常明显的东西。
如果重要:这只是 CodeWars 上的一个套路,它让我想到了一个关于数据类型和 for..in 循环机制的基本问题。这似乎非常相关,但不是 100% 符合我的问题:"for" vs "each" in Ruby。
在此先感谢您的帮助。
编辑:
好的,我想我明白了。不过,我仍然喜欢一些答案,以确认、澄清或彻底反驳。
我意识到如果我想使用 for 循环,我应该使用数组本身作为 "range" 而不是“0..array.length”,像这样:
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
for i in string_array
if vowels.include?(i)
result+= "!"
else
result+=i
end
end
puts result
所以,是不是因为"each"方法变量(在本例中,"i")不存在于主块的范围之外,所以在评估它是否是后,它的数据类型变成了nil包含在 'vowels' 数组中?
你的 for
循环:
for i in 0..string_array.length
从 0 到 10 循环。
但是 string[10] #=> nil
因为索引 10 处没有元素。然后在第 9 行你尝试将 nil
添加到 result
result = result + string_array[i] #expanded
您不能将 nil
添加到这样的字符串中,您必须将 nil
显式转换为字符串,从而出现错误。解决此问题的最佳方法是将 for 循环更改为:
for i in 0..string_array.length-1
然后你的循环将在最后一个元素处结束,string[9]
。
您在迭代以索引 0 开始的数组时被 class 逻辑错误打败了,而不是长度作为结束位置,它应该是长度 1。
但是看起来你来自其他一些编程语言,你的代码不是Rubyesque,例如很少使用'For'。
Ruby 是一种比大多数其他语言更高级的语言,它内置了很多解决方案,我们称它为 'sugared' 因为 Ruby 是为了让我们程序员开心。您尝试实现的目标只需一行即可完成。
"helloHELLO".scan(/[aeoui]/i).count
一些解释:文字数组 "hello HELLO" 是一个字符串,意思是字符串 class 的一个对象,因此有很多方法可以使用,比如 scan,它扫描字符串对于正则表达式 /[aeoui]/,它表示 [] 中包含的任何字符,末尾的 i 使其不区分大小写,因此您不必添加 AEOUI。扫描 returns 具有匹配字符的数组,数组 class 的对象具有方法计数,这给了我们......是的,一旦你明白了就很容易,你可以将方法串在一起它们相互作用。
我正在寻求一些帮助来理解为什么在尝试使用 for 循环搜索字母数组(并将它们添加到结果字符串中)时出现错误(没有将 nil 隐式转换为字符串) ,这似乎是真正的问题),但当我出于相同目的使用 while 循环或 'each' 时却不是。我查看了很多文档,但无法找到为什么会发生这种情况的答案。我知道我可以只使用 "each" 方法并收工,但我更愿意理解原因和结果(并希望将来避免这个问题)。
下面的方法可以正常工作:打印 "result" 这是原始字符串,只有 "!"代替任何元音。
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
string_array.each do |i|
if vowels.include?(i)
result+="!"
else
result+=i
end
end
puts result
但是,我最初的尝试(在下面发布)引发了上述错误:"no implicit conversion of nil into String" 引用第 5 行和第 9 行。
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
for i in 0..string_array.length
if vowels.include?(string_array[i])
result+= "!"
else
result+=string_array[i]
end
end
puts result
通过实验,我设法让它工作了;我确定——通过打印到屏幕而不是存储在 "result" 中——问题发生在目标字母与字符串 "result" 的连接过程中。但为什么 "string_array[i]" (第 9 行)被视为 NIL 而不是字符串?我觉得我错过了一些非常明显的东西。
如果重要:这只是 CodeWars 上的一个套路,它让我想到了一个关于数据类型和 for..in 循环机制的基本问题。这似乎非常相关,但不是 100% 符合我的问题:"for" vs "each" in Ruby。
在此先感谢您的帮助。
编辑:
好的,我想我明白了。不过,我仍然喜欢一些答案,以确认、澄清或彻底反驳。
我意识到如果我想使用 for 循环,我应该使用数组本身作为 "range" 而不是“0..array.length”,像这样:
s="helloHELLO"
result=""
vowels=["a","e","i","o","u","A","E","I","O","U"]
string_array=s.split("")
for i in string_array
if vowels.include?(i)
result+= "!"
else
result+=i
end
end
puts result
所以,是不是因为"each"方法变量(在本例中,"i")不存在于主块的范围之外,所以在评估它是否是后,它的数据类型变成了nil包含在 'vowels' 数组中?
你的 for
循环:
for i in 0..string_array.length
从 0 到 10 循环。
但是 string[10] #=> nil
因为索引 10 处没有元素。然后在第 9 行你尝试将 nil
添加到 result
result = result + string_array[i] #expanded
您不能将 nil
添加到这样的字符串中,您必须将 nil
显式转换为字符串,从而出现错误。解决此问题的最佳方法是将 for 循环更改为:
for i in 0..string_array.length-1
然后你的循环将在最后一个元素处结束,string[9]
。
您在迭代以索引 0 开始的数组时被 class 逻辑错误打败了,而不是长度作为结束位置,它应该是长度 1。 但是看起来你来自其他一些编程语言,你的代码不是Rubyesque,例如很少使用'For'。 Ruby 是一种比大多数其他语言更高级的语言,它内置了很多解决方案,我们称它为 'sugared' 因为 Ruby 是为了让我们程序员开心。您尝试实现的目标只需一行即可完成。
"helloHELLO".scan(/[aeoui]/i).count
一些解释:文字数组 "hello HELLO" 是一个字符串,意思是字符串 class 的一个对象,因此有很多方法可以使用,比如 scan,它扫描字符串对于正则表达式 /[aeoui]/,它表示 [] 中包含的任何字符,末尾的 i 使其不区分大小写,因此您不必添加 AEOUI。扫描 returns 具有匹配字符的数组,数组 class 的对象具有方法计数,这给了我们......是的,一旦你明白了就很容易,你可以将方法串在一起它们相互作用。