2016-05-23 47 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