你translate
方法不會工作。問題就在這裏:
if word[0] == "a" || "e" || "o" || "u" || "i"
和
elsif word[0] != "a" || "e" || "o" || "u" || "i"
您可以這種方式無法比擬的任右邊不會做你認爲它會。
一些簡單的檢查將說明爲什麼有些不對勁:
'abc'[0] == "a" || "e" || "o" || "u" || "i" # => true
'efg'[0] == "a" || "e" || "o" || "u" || "i" # => "e"
'opq'[0] == "a" || "e" || "o" || "u" || "i" # => "e"
'xyz'[0] == "a" || "e" || "o" || "u" || "i" # => "e"
'abc'[0] != "a" || "e" || "o" || "u" || "i" # => "e"
'efg'[0] != "a" || "e" || "o" || "u" || "i" # => true
'opq'[0] != "a" || "e" || "o" || "u" || "i" # => true
'xyz'[0] != "a" || "e" || "o" || "u" || "i" # => true
爲什麼這些錯誤?讓我們來看看發生了什麼:
當這個詞與「A」開始,測試'a' == 'a'
是正確的:
'abc'[0] == "a" # => true
如果我們||
(「或」)真實的東西,我們得到真正的回來,因爲它在第一個「真」值看出:
true || "e" # => true
如果首次測試失敗,則||
導致第二測試進行評估,這在你的代碼是"e"
,而不是一個測試,但沒紅寶石」不知道,並認爲這是一個「tr UE」返回值,以便它成爲表達式的結果:
false || "e" # => "e"
知道了,寫這個正確的方法是:
'abc'[0] == "a" || 'abc'[0] == "e" || 'abc'[0] == "o" || 'abc'[0] == "u" || 'abc'[0] == "i" # => true
'efg'[0] == "a" || 'efg'[0] == "e" || 'efg'[0] == "o" || 'efg'[0] == "u" || 'efg'[0] == "i" # => true
'opq'[0] == "a" || 'opq'[0] == "e" || 'opq'[0] == "o" || 'opq'[0] == "u" || 'opq'[0] == "i" # => true
'xyz'[0] == "a" || 'xyz'[0] == "e" || 'xyz'[0] == "o" || 'xyz'[0] == "u" || 'xyz'[0] == "i" # => false
'abc'[0] != "a" && 'abc'[0] != "e" && 'abc'[0] != "o" && 'abc'[0] != "u" && 'abc'[0] != "i" # => false
'efg'[0] != "a" && 'efg'[0] != "e" && 'efg'[0] != "o" && 'efg'[0] != "u" && 'efg'[0] != "i" # => false
'opq'[0] != "a" && 'opq'[0] != "e" && 'opq'[0] != "o" && 'opq'[0] != "u" && 'opq'[0] != "i" # => false
'xyz'[0] != "a" && 'xyz'[0] != "e" && 'xyz'[0] != "o" && 'xyz'[0] != "u" && 'xyz'[0] != "i" # => true
然而,迅速變得難以閱讀和笨重,所以需要更簡潔的東西:
%w[a e o u].include? 'abc'[0] # => true
%w[a e o u].include? 'efg'[0] # => true
%w[a e o u].include? 'opq'[0] # => true
%w[a e o u].include? 'xyz'[0] # => false
!%w[a e o u].include? 'abc'[0] # => false
!%w[a e o u].include? 'efg'[0] # => false
!%w[a e o u].include? 'opq'[0] # => false
!%w[a e o u].include? 'xyz'[0] # => true
雖然有一個問題,隨着數組大小的增加,需要更多的循環與[0]
值進行比較,這會不必要地降低代碼的速度。正則表達式,正確書寫,可以擺脫循環,這樣的速度保持非常穩定:
'abc'[0][/[aeou]/] # => "a"
'efg'[0][/[aeou]/] # => "e"
'opq'[0][/[aeou]/] # => "o"
'xyz'[0][/[aeou]/] # => nil
注意雖然,而不是讓真/假,結果是由圖案或無匹配的字符。在Ruby中,只有nil和false被認爲是假的值,其他的都是真的,所以我們可以分別將它們轉換爲true,true,true和false,但是通過利用!
運算符,我們可以更加清楚:
!!'abc'[0][/[aeou]/] # => true
!!'efg'[0][/[aeou]/] # => true
!!'opq'[0][/[aeou]/] # => true
!!'xyz'[0][/[aeou]/] # => false
可能看起來我們不得不使用!!!
「不」的結果一樣,我們會使用!=
時想要的,但不是必要的。一個!
將做同樣的事情:
!'abc'[0][/[aeou]/] # => false
!'efg'[0][/[aeou]/] # => false
!'opq'[0][/[aeou]/] # => false
!'xyz'[0][/[aeou]/] # => true
但是等等!還有更多!即使通過刪除字符串片段([0]
)並使用正則表達式錨點,也可以稍微提高這一點。比較這兩種,它們的基準:
require 'fruity'
ALPHABET = ('a'..'z').to_a.join
compare do
slice_it { ALPHABET[0][/[aeou]/] }
regex_it { ALPHABET[/^[aeou]/] }
end
# >> Running each test 8192 times. Test will take about 1 second.
# >> regex_it is faster than slice_it by 39.99999999999999% ± 10.0%
因此,使用這樣的:
'abc'[/^[aeou]/] # => "a"
!'abc'[/^[aeou]/] # => false
!!'abc'[/^[aeou]/] # => true
將是快速和緊湊,讓你測試一下,看看有什麼字符串開始。
您需要爲''PigLatin'模塊添加一個'translate'方法。我不知道'Word'類與這個有什麼關係,除了你可能希望移動那裏的功能並使'translate'使用那個類。這個問題太廣泛,無法進一步回答。 – meagar 2014-11-05 19:05:41
Iway ouldway agreeway ithway @eagarmay atthay ethay estionquay isway ootay oadbray。 – 2014-11-05 20:53:21