2014-12-10 1 views
0

У меня есть массив user_list, который содержит пользователей. Каждый пользователь имеет хэш и имеет символ: имя.Попытка заменить ruby ​​if заявление тройной, разрывы кода

Я работаю с электронной таблицей, а для строки первый столбец aka row [0] содержит имя. Если я хочу обновить хэш пользователя с данными из остальных столбцов строки, мне нужно получить правильный хэш пользователя из user_list.

Здесь ниже код, который работает:

def self.retrieve_user(user_list, row) 
    user_list.each do |user| 
     if user[:name] == row[0] 
     return user 
     end 
    end 
end 

Я пытался заменить его следующим образом:

def self.retrieve_user(user_list, row) 
    user_list.each do |user| 
     user[:name] == row[0] ? user : nil 
    end 
end 

И теперь моя программа ломается. Что мне не хватает в отношении тройного оператора?

Edit: Я пытаюсь сделать это из-за https://github.com/bbatsov/ruby-style-guide

ответ

3

В первой версии вашей программы, вы перебора списка пользователей и когда вы нашли пользователь, которого вы хотели, вы вернули пользователь, кто называется (таким образом, сразу же разрывая петлю each, а также функцию retrieve_user).

В вашей второй версии вы явно не возвращаете какие-либо значения, ничего не делается с этим объектом user, который вы получаете, он просто продолжает выполнение цикла до тех пор, пока он не будет закрыт в конце user_list and then it returns the user_list` неявно (это является функцией Ruby). Смотрите следующий пост в блоге, который объясняет это хорошо: http://www.thedwick.com/2012/08/ruby-implicit-returns-do-as-the-romans-do/

Вы можете заменить код следующим добиться того, что вы изначально хотели в одной строке

def self.retrieve_user(user_list, row) 
    user_list.each do |user| 
     return user if user[:name] == row[0] 
    end 
end 

Вы также должны рассмотреть случай, когда ни один из пользователей в списке пользователей совпадают с именем пользователя (если вы не уверены, что этого не произойдет). В приведенном выше случае весь список пользователей будет неявным образом возвращен, так как return user не будет выполняться, поскольку условие всегда ложно. Вы можете добавить явное возвращение ноль в конце, если ничего не должно быть возвращено:

def self.retrieve_user(user_list, row) 
    user_list.each do |user| 
     return user if user[:name] == row[0] 
    end 
    return nil 
end 
+0

большое спасибо, прежде чем я даже попасть в раздел, требующий получения пользователем, я анализирую таблицу для получения всех пользователей (так что я могу добавить их хэшей user_list), поэтому я поеду с вашим первым предложением! – MMP

2

Я предложил бы использовать Enumerable#find

Из документов:

Передает каждую запись в перечислить для блокировки. Возвращает первый, для которого блок не является ложным. Если объект не совпадает, вызывает ifnone и возвращает результат , если он указан, или возвращает нуль в противном случае.

Вот как это выглядит:

def self.retrieve_user(user_list, row) 
    user_list.find{|user| user[:name] == row[0] } 
end 
+1

это действительно аккуратно! – MMP

Смежные вопросы