Как написать условное утверждение в одну строку?рельсы - PullRequest
1 голос
/ 07 января 2011

Я пытаюсь сказать это

self.preferred_amount * object.each{|li|li.variant}.collect{|li|li.weight}

Единственная проблема заключается в том, что определенные веса равны нулю.

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

Есть ли способ включить эту логику в одну строку?

Или есть ли способ сделать это утверждение еще более реорганизованным, чем оно есть?

Ответы [ 5 ]

8 голосов
/ 07 января 2011

Изменить li.weight на li.weight || 0

|| - оператор «короткого замыкания или». Если его левая часть верна (ни ложь, ни ноль), она возвращает левую сторону, в противном случае она возвращает правую сторону.

В MRI есть функция> = 1.8.7, которая позволит вам сделать это более кратким. Вместо:

each{|li|li.variant}

Вы можете написать

each(&:variant)

В версиях Ruby до 1.8.7 требуется гем backports для получения этой функции.

Лучше перенести всю логику в класс объекта, например,

class Whatever
  def variant_weights
    each(&:variant).collect{ |li| li.weight || 0}
  end
end

и использовать его:

self.preferred_amount * object.variant_weights

Однако обратите внимание, что ошибка умножения скалярного значения на массив. Если вы хотите суммировать веса, то:

class Whatever
  def total_variant_weights
    each(&:variant).collect{ |li| li.weight || 0}.inject(&:+)
  end
end

и использовать его:

self.preferred_amount * object.total_variant_weights
5 голосов
/ 07 января 2011

Обратите внимание, что все приведенные выше ответы правильны для вашей цели, но чтобы ответить на ваш вопрос напрямую:

Как написать условное утверждение в одну строку?Rails

Вы можете использовать троичные операторы.Они принимают следующую форму:

assertion ? value_if_true : value_if_false
# if assertion is true, then value_if_true, otherwise, value_if_false

, например:

puts 4 < 5 ? 'you are on Earth' : 'you are on another planet'
<%= @user.is_admin? ? 'you can access this page' : 'you aren\'t allowed to be here' %>

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

Также обратите внимание, что это не относится к Ruby.Большинство языков программирования (включая Ruby, PHP, CF, AS, JAVA, C, C # ...) имеют троичные операторы.

2 голосов
/ 07 января 2011

Каждый кажется излишним.А как насчет:

self.preferred_amount * object.collect { |o| o.variant.weight.to_i }

или если вы действительно хотели сложить веса:

self.preferred_amount * object.inject { |sum, o| sum + o.variant.weight.to_i }

2 голосов
/ 07 января 2011

Попробуйте

 .collect{|li|li.weight || 0}
2 голосов
/ 07 января 2011

просто || 0 вес:

self.preferred_amount * object.each{|li|li.variant}.collect{|li|li.weight || 0}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...