我遇到了一个关于Codewars问题的奇怪事情。以下是说明:
写一个函数toWeirdCase(Ruby中的怪异)接受一个字符串,并返回相同的字符串,每个单词大写字母中包含所有偶数索引字符,并且每个单词中的所有奇数索引字符都更低。刚解释的索引是基于零的,所以零第i个索引是偶数,因此该字符应该是大写的。
传入的字符串只包含字母字符和空格('')。只有在有多个单词时才会出现空格。单词将由单个空格分隔('')。 例子:
weirdcase( "String" )#=> returns "StRiNg"
weirdcase( "Weird string case" );#=> returns "WeIrD StRiNg CaSe"
这是我的代码:
def weirdcase string
@case = []
# Ternary:
string.each_char { |c|
# string.index(c).even? ? @case.push(c.upcase) : @case.push(c.downcase)
c =~ /[[:alpha:]]/ ? (string.index(c).even? ? (@case.push(c.upcase)) : (@case.push(c.downcase))) : (string.index(c) + 1)
}
# If/Then:
# string.each_char { |c|
#if string.index(c).even? && c != " "
# if c =~ /[[:alpha:]]/ && string.index(c).even?
# then @case.push(c.upcase)
# else @case.push(c.downcase)
# end }
@case.join
end
p "TEST"
p weirdcase "this is a test"
p weirdcase "thisisatest"
p weirdcase " th is is a t es t"
结果:
"TEST"
"ThIsIsATesT"
"ThIsIsATEsT"
"tHIsIsAtest"
weirdcase
should return the correct value for multiple words
Expected: "ThIs Is A TeSt", instead got: "ThIsIsATesT"
0 Passed
1 Failed
0 Errors
Process took 171ms to complete
以下是测试:
describe 'weirdcase' do
#it 'should return the correct value for a single word' do
# Test.assert_equals(weirdcase('This'), 'ThIs');
# Test.assert_equals(weirdcase('is'), 'Is');
#end
it 'should return the correct value for multiple words' do
Test.assert_equals(weirdcase('This is a test'), 'ThIs Is A TeSt');
end
end
我尝试过几种不同的方式来编写这些代码,并且我不断得到相同的结果:而不是"这是一个很好的方式"结果,我得到了#34; ThIsIsATesT"或者其他一些变化,其中交替的大写似乎一旦到达单词" test"就会失败,这对我来说没有任何意义 - 它似乎违背了这些方法应该做的事情。我也在irb中尝试过,看到了相同的结果,所以我不会认为是一个Codewars错误。
我在Ruby上还是比较新的。任何人都可以帮我找到我必须忽略的事情和/或解释这个代码是如何产生这个结果的吗?
每个人,谢谢你的好建议。我将标题更新为更具描述性的内容,并从头开始重新编写此代码,以单独索引迭代每个单词,而不是将其视为一个长字符串。我虽然仍然遇到麻烦。这是我的新代码:
def weirdcase string
char = Array.new
puts "string: #{string}"
string.split(' ').each do |word|
word.each_char.with_index do |c, index|
if index.even?
char.push(c.upcase)
else
char.push(c.downcase)
end
end
end
puts "char: #{char}"
puts "char.join(''): #{char.join('')}"
puts "char.join('space'): #{char.join(' ')}"
end
以下是结果:
weirdcase
should return the correct value for multiple words
string: This is a test
char: ["T", "h", "I", "s", "I", "s", "A", "T", "e", "S", "t"]
char.join(''): ThIsIsATeSt
char.join('space'): T h I s I s A T e S t
Expected: "ThIs Is A TeSt", instead got: nil
所以我现在遇到的麻烦就是如何在两者之间正确地连接单词,而不是你在上面看到的。我在初次拆分后正在查找正确访问数组条目的方法。但当然我会欢迎任何人可能提供的更多提示:)
答案 0 :(得分:1)
我认为你的许多问题都是由这部分代码引起的:
string.index(c).even?
假设c
等于'T'
。然后string.index(c)
将始终返回字符串中第一个字母T的索引,该索引始终为零,即使您尝试处理字符串后面部分中的一个T字母。
要在迭代它们时获取字符索引,这样的事情应该有效:
string.each_char.with_index do |c, index|
if index.even?
#...
else
#...
end
end
答案 1 :(得分:1)
如另一个答案中所述,index(c)
调用是当前代码的主要问题。它将返回与请求的字符串匹配的字符串中的第一个索引(区分大小写)。给定您的测试字符串"this is a test"
,因为第一个" t"索引0(偶数)ALL(小写)t将被大写,并且自第一个" s"索引3(奇数)ALL(小写)s&s 39将是小写的。也就是说,看起来你可能会略微误读问题的一部分:
所有偶数索引的字符在每个单词大写字母中,并且所有奇数索引字符在每个单词中小写。
在他们的例子中,他们给你这个
weirdcase( "Weird string case" );#=> returns "WeIrD StRiNg CaSe"
如果仔细观察,基于该示例,对于多字符串,它不是基于字符串中的绝对索引,而是基于每个单词中每个字母的索引。如果是前者,则会看到此转换(e =偶数索引,o =奇数索引)
eoeoeoeoeoeoeoeoe
"Weird string case" # => WeIrD StRiNg cAsE
因为" c"如果是一个奇数索引,所以它会小写。但是从它们的例子来看,它是大写的 - 每个单词都被视为单词中的第一个字母是该单词的索引0。
我建议a)编写一个方法,将字符串应用于字符串中的每个单词,b)将字符串拆分为单词,并使用您刚编写的方法单独应用每个单词,并c)将它们连接起来一起(不要忘记指定加入他们的角色,例如join(' ')
。
答案 2 :(得分:1)
经过多次试验和错误,我设法将一些有效的东西放在一起:
def weirdcase string
arr, char, result = [],[],[]
arr = string.split(' ').each_slice(string.split(' ').count).to_a.transpose
arr.each_with_index do |arr_word, index|
arr_word.each_with_index do |word, sub_index|
word.each_char.with_index do |letter, letter_index|
letter_index.even? ? char.push(letter.upcase) : char.push(letter.downcase)
end
end
result.push(char.join(''))
char.clear
end
result.join(' ')
end
它很笨重,可能效率不高,但它有效。我必须:
然后清除“char”数组,这样就不会迭代地将这些单词连接在一起,如下所示:
[ “这个”, “THISIS”, “ThIsIsA”, “ThIsIsATeSt”]
它从每次迭代的最开始开始,并且随着时间的推移将所有单词粘在一起。这是最难弄清楚的部分。我使用了很多put语句来进行错误检查,并且在我弄清楚它之前不得不进行大量的反复试验。我想有一种方法可以让它从一个数组元素移动到下一个数组元素,而不是每次都从头开始,但出于挫折感,我使用'char.clear'作为解决方法。就像我说的那样,它很笨重。拥有3个嵌套的'do'语句或3个独立的数组似乎也没有效率。任何人都可以提出任何建议,使代码更有效和/或更多Ruby-ish?
如果我能想出一个改进的版本,我会在这里添加它。如果你很好奇,这里是Codewars-Submit-Test结果:
weirdcase
should return the correct value for a single word
Test Passed: Value == "ThIs"
Test Passed: Value == "Is"
Test Passed: Value == "A"
Test Passed: Value == "TeSt"
Test Passed: Value == "LoOkS"
Test Passed: Value == "LiKe"
Test Passed: Value == "YoU"
Test Passed: Value == "PaSsEd"
should return the correct value for multiple words
Test Passed: Value == "ThIs Is A TeSt"
Test Passed: Value == "LoOkS LiKe YoU PaSsEd"
Test Passed: Value == "ThIs Is ThE FiNaL TeSt CaSe"
Test Passed: Value == "JuSt KiDdInG"
Test Passed: Value == "Ok FiNe YoU ArE DoNe NoW"