在Ruby中,将元音更改为字符串中的索引号的程序
这是一个将元音更改为其索引的程序:在Ruby中,将元音更改为字符串中的索引号的程序,ruby,Ruby,这是一个将元音更改为其索引的程序: def vowel_2_index(string) return '' if string.nil? arr = string.enum_for(:scan,/[aeiou]/i).map {Regexp.last_match.begin(0) } s_arr = arr.map{|x| x+1 } arr.each_with_index{|x,y| string[x] = s_arr[y].to_s} s
def vowel_2_index(string)
return '' if string.nil?
arr = string.enum_for(:scan,/[aeiou]/i).map {Regexp.last_match.begin(0) }
s_arr = arr.map{|x| x+1 }
arr.each_with_index{|x,y| string[x] = s_arr[y].to_s}
string
end
有谁能告诉我为什么它没能通过“Codewars是世界上最好的网站”
当我试图通过测试用例时,如:
Test.assert_equals(vowel_2_index('Codewars is the best site in the world'),'C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld')
它的输出类似于:
"C2d4w6rs 10s t15e18bes232527ite32i35 the world"
如您所见,当您开始用位置替换元音时,当位置为一位数(即
1
或5
)时,它会起作用,但当位置变为两位数(10
或更大)时,所有找到的索引都会开始移动,并且arr
信息不再正确
我建议使用,因为您想进行全局搜索和替换,您几乎做对了:
str = 'Codewars is the best site in the world'
str.gsub(/[aeiou]/) { |item| Regexp.last_match.begin(0) + 1 }
# => "C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld"
以下所有内容均指:
str = 'Codewars is the best site in the world'
至于你遇到的问题,让我们把它分解一下:
enum = str.enum_for(:scan,/[aeiou]/i)
#=> #<Enumerator: "Codewars is the best site in the world":scan(/[aeiou]/i)>
继续:
arr = enum.map {Regexp.last_match.begin(0) }
#=> [1, 3, 5, 9, 14, 17, 22, 24, 26, 31, 34]
s_arr = arr.map{|x| x+1 }
#=> [2, 4, 6, 10, 15, 18, 23, 25, 27, 32, 35]
arr.each_with_index{|x,y| string[x] = s_arr[y].to_s}
#=> [1, 3, 5, 9, 14, 17, 22, 24, 26, 31, 34]
str
#=> "C2d4w6rs 10s t15e18bes232527ite32i35 the world"
该方法应返回:
#=> "C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld"
因此,您可以看到分歧从'the'
中的'h'
开始,它位于索引13
。当arr
的元素10
被传递到块时,就会出现问题。在这一点上,
str
#=> "C2d4w6rs is the best site in the world"
块变量设置为:
x,y = [10, 3]
x #=> 10
y #=> 3
因此,区块计算为:
str[10] = s_arr[3].to_s
#=> = "10"
现在:
str
#=> "C2d4w6rs 10s the best site in the world"
如您所见,10
后面的所有字母的索引都增加了一个。这在早些时候不是问题,因为前三个字符都被替换为一个数字。arr
和s_-arr
的其余元素现在被关闭1,在下一次替换之后,其余元素的索引将被关闭2,依此类推
*********
我将使用以下方法之一
VOWELS = 'aeiouAEIOU'
#1
pos = '0'
str.gsub(/./) { |c| pos.next!; VOWELS.include?(c) ? pos : c }
#=> "C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld"
#2
str.each_char.with_index(1).map { |c,i| VOWELS.include?(c) ? i.to_s : c }.join
#=> "C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld"
#3
str.size.times.map { |i| VOWELS.include?(str[i]) ? (i+1).to_s : str[i] }.join
#=> "C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld"
我稍微偏爱#1,因为它直接对字符串进行操作,而不是创建一个数组,然后将其元素连接回字符串。此外,我认为它读起来最好
str = 'Codewars is the best site in the world'
您可以将字符串拆分为字符数组,并使用with_索引(1)将每个值与regex.Am进行比较,因为数组是基于零的
str.split(//).map.with_index(1){|k,v| /[aeiou]/=~k ? v : k}.join
其结果是:
#=> 'C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld'
谢天谢地,我不知道ruby中索引的这种行为..在你的帮助下解决了我的问题..谢天谢地,我不是以英语为母语的人,所以如果我的评论对你来说粗鲁或不合适,请原谅我。您是否建议不推广我自己的答案,而是对接受答案进行一般教育,并要求OP选择答案?如果是这样的话,我同意,那是公平的。对不起,你没有完全理解你的评论……你能告诉我确切的意思吗?我搞错了吗?Jay,Alexey的评论是对我留下并随后删除的评论的回复。谢谢……是的,我为我的问题找到了另一种解决方案,比如
string.chars.each_with_index.map{c,i |[aeiou]/i.match(c)?(i+1)。to_s:c}.join
…只想知道为什么上述解决方案不起作用…..索引的行为是什么…..我没有充分解释您问题中的代码问题吗?您的解释对我来说非常清楚。。。。。。。我非常感谢您的帮助,而且方法1对我来说非常聪明和独特。谢谢你的关心。。。。
#=> 'C2d4w6rs 10s th15 b18st s23t25 27n th32 w35rld'