2015-03-19 25 views
1

這段代碼(它是更大代碼的一部分)的目的是確定一年中是否有重複的數字。這是我的代碼:爲什麼我的回報弄亂了我的結果?

def no_repeat?(year) 
    year = year.to_s 
    string = '' 

    year.each_char{|i| string << year[i] unless string.include?(year[i])} 
    year.length == string.length ? (return false) : (return true) 
    end 

puts no_repeat?(1993) 

它總是返回true,我看不出爲什麼發生這種情況。我試圖將三元語法擴展爲完整的if語句...仍然返回true。我曾嘗試寫這整個方法作爲一個while循環(帶有兩個指標一個指標比較其他)

def no_repeat?(year) 
    year = year.to_s 

i = 0 
while i < year.length 

    i2 = i + 1 
    while i2 < year.length 

     if year[i] == year[i2] 
     return false 
     else 
     return true 
     end 

     i2 += 1 
    end 
    i += 1 
end 

...還是返回true。我已經獨立地測試了每件事情,並且它們都工作正常,直到我把回報放入。什麼是回報?我需要新鮮的眼睛。

回答

2

您構建三元組的方式不正確。由於您的方法試圖確保沒有重複,因此當==爲真時,它應返回true。三元本身是爲了返回一個值,而不是真的在其結果中執行像(return false)這樣的表達式。那工作,但是對於實際上不存在是非常規的。

三元應該像

return year.length == string.length ? true : false 

這當然可以被簡化,因爲==表達已經返回一個布爾值。

return year.length == string.length 

接下來,您使用year[i]是不太正確的。 String#each_char正在將字符值分配到i,因此您可以直接使用i。看起來你已經使用它的方式確實有效,但這並不意味着要使用迭代器變量i

這使得你的方法爲:

def no_repeat?(year) 
    year = year.to_s 
    string = '' 

    # i represents the character in this iteration 
    # so you may just directly reference i here 
    year.each_char{|i| string << i unless string.include?(i)} 
    # If the lengths match, return true because there's no repeating character 
    return year.length == string.length 

    # You could omit the 'return' keyword too which is preferred by convention 
    # since Ruby returns the last expression's value implicitly 
    # year.length == string.length 
end 
+0

是,each_char正在評估自己,哈哈,我不能相信我沒有趕上的字符當我真的知道,我很習慣寫while循環(試圖突破),你必須區分[i]和object [i] ....在這種情況下,如果沒有重複,我希望方法返回true;如果有,則返回false,這就是爲什麼如果i == i2,那麼將會有重複,因此第一次返回是錯誤的。總體而言,你的建議,以省略真正的假回報一起工作!再次,爲什麼我沒有想到這個?!tuh!我仍然是一個新手,哈哈,謝謝! – HolyMoly 2015-03-19 01:47:07

+0

但很快,只要它是您希望檢查的條件的結果,那麼您放置的順序是否真的很重要?像我一樣?紅寶石只會按照一定的順序讀取它們嗎?我實際上已經嘗試過切換它們,並且它保持返回false,它似乎是跳過第一個返回(無論是在三元組還是while循環中)..爲什麼? – HolyMoly 2015-03-19 01:51:14

+1

它確實很重要。如果條件爲真,結果必須放在第一位,所以如果你想反轉,你會首先放置'假'(在'?'後面)。如果你一直得到錯誤的回報,我還不確定其原因,但它可能是一個古怪的迴歸表達式,而不是三元結果。在while循環中,我沒有試驗過你的代碼,看看它是如何表現的。重要的是使用三元表達式來返回或分配像'var = bool_expression? val_if_true:val_if_false'而不是嘗試在其中放置一個'return' – 2015-03-19 02:11:10

2

你有翻轉的真實和虛假陳述。否則代碼工作。

這工作:

def no_repeat?(year) 
    year = year.to_s 
    string = '' 

    year.each_char{|i| string << year[i] unless string.include?(year[i])} 
    year.length == string.length ? (return true) : (return false) 
end 

no_repeat?(1993) # => false 
no_repeat?(2015) # => true 

但是有很多方法,你應該提高這個代碼。在Ruby中很少使用return關鍵字。事實上,在你的例子中它是完全多餘的。這兩種方法是等價的:

# with `return` 
def no_repeat?(year) 
    year = year.to_s 
    string = '' 

    year.each_char{|i| string << year[i] unless string.include?(year[i])} 
    year.length == string.length ? (return true) : (return false) 
end 

# without `return` 
def no_repeat?(year) 
    year = year.to_s 
    string = '' 

    year.each_char{|i| string << year[i] unless string.include?(year[i])} 
    year.length == string.length 
end 

其次,在方法名中使用否定(「no」)會使代碼難以遵循。我建議翻轉邏輯並調用方法repeat?或甚至更好repeat_chars?

最後,還有更簡潔的方式來表達您使用內置Ruby方法編寫的邏輯。這是一個可選的實現(我敢肯定,其他的Ruby開發者可以附和更優雅的解決方案):

def repeat_chars?(year) 
    year = year.to_s 
    year.length != year.chars.uniq.length 
end 
+0

我同意這個方法的名字很混亂,但這就是練習告訴我們命名它的原因(我應該更頻繁地違反規則)。正因爲如此,我首先回歸錯誤,因爲在比較之後,我更加明智。我愛你最終的解決方案,絕對更優雅。 – HolyMoly 2015-03-19 01:58:55

相關問題