2016-05-23 23 views
-2

我是編程和ruby的新手。我正在使用一種方法來識別誰是某人的祕密聖誕老人。該方法使用String和Integer參數(名字或ID)。我有不同的String和Integer參數的代碼。這會導致對不同參數(secret = PERSONS [person [:santa] -1])重複相同的代碼行。DRY在Ruby中 - 可以重複一行代碼嗎?

我的問題有兩方面:

  1. 就是這種對DRY原則的重複?是否有另一種避免重複的方法?

  2. 看到我初始化迭代器外部的local_variable secret並使用迭代器傳遞給該變量。這是做這件事最有效的方法嗎?我可以直接從迭代器中返回一個值而不用初始化局部變量嗎?

我的代碼如下。另外,我正在附上我正在運行代碼的數據(人員)樣本散列。

def who_is_secret_santa(first_name) 
    secret = nil 
    PERSONS.each do |person| 
    if first_name.is_a? String 
     if person[:first_name] == first_name 
     secret = PERSONS[person[:santa]-1] 
     end 
    elsif first_name.is_a? Integer 
     if person[:id] == first_name 
     secret = PERSONS[person[:santa]-1] 
     end 
    else 
     puts "Bad argument" 
    end 
    end 
    puts "#{first_name}'s Secret Santa " + (secret ? "is #{secret[:first_name]}" : "not found") 
end 


[{:id=>1, 
    :first_name=>"Luke", 
    :last_name=>"Skywalker", 
    :email=>"<[email protected]>", 
    :santa=>4}, 
{:id=>2, 
    :first_name=>"Leia", 
    :last_name=>"Skywalker", 
    :email=>"<[email protected]>", 
    :santa=>7}, 
{:id=>3, 
    :first_name=>"Toula", 
    :last_name=>"Portokalos", 
    :email=>"<[email protected]>", 
    :santa=>5}, 
{:id=>4, 
    :first_name=>"Gus", 
    :last_name=>"Portokalos", 
    :email=>"<[email protected]>", 
    :santa=>2}, 
{:id=>5, 
    :first_name=>"Bruce", 
    :last_name=>"Wayne", 
    :email=>"<[email protected]imbatman.com>", 
    :santa=>3}, 
{:id=>6, 
    :first_name=>"Virgil", 
    :last_name=>"Brigman", 
    :email=>"<[email protected]>", 
    :santa=>1}, 
{:id=>7, 
    :first_name=>"Lindsey", 
    :last_name=>"Brigman", 
    :email=>"<[email protected]>", 
    :santa=>6}] 
+0

看看這個:http://rubyofftherails.blogspot.com.br/2016/05/better-algorithms.html –

+0

這不是你的特定代碼,但是可以幫助你與DRY原則。 –

回答

1

還有就是要避免在這種情況下重複首先檢查了「錯誤的參數」,然後再把從陣列中選擇正確的人的一種方式。

對於第二個問題,您可能正在尋找select迭代器而不是每個。它將返回數組中所有傳遞給它的條件爲true的元素。

下面是一些代碼。 p將表示first_name傳遞給方法的人員。

def who_is_secret_santa(first_name) 
    if ! ((first_name.is_a? String) || (first_name.is_a? Integer)) 
    puts "Bad argument" 
    else 
    p = (PERSONS.select do |person| person[:first_name] == first_name || person[:id] == first_name end)[0] 
    puts "#{first_name}'s Secret Santa " + (p ? "is #{PERSONS[p[:santa]-1][:first_name]}" : "not found") 
    end 
end