2016-05-23 2 views
-2

Я новичок в программировании и рубине. Я использую метод, чтобы определить, кто чья-то секретная Санта. Метод принимает аргументы String и Integer (имя или идентификатор). У меня есть другой код для аргументов String и Integer. Это приводит к повторению одной и той же строки кода для разных аргументов (secret = PERSONS [person [: santa] -1]).DRY в Ruby - Можно ли повторить строку кода?

Мои вопросы два раза:

  1. Является ли это своего рода повторение против СУХИХ принципов? Есть ли другой способ избежать повторения?

  2. Посмотрите, что я инициализировал локальный_вариабельный секрет вне итератора и использовал итератор для передачи этой переменной. Это самый эффективный способ сделать это? Могу ли я просто вернуть значение из итератора без инициализации локальной переменной?

Мой код ниже. Кроме того, я включаю образец хэша данных (PERSONS), на котором я запускаю код.

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]>", 
    :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

Это не о вашем конкретном коде, но может помочь вам с СУХОЙ принципе. –

ответ

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 
Смежные вопросы