Reputation: 2382
I am trying to reject array items based on multiple conditions.
The code is as follows
def fetch_items
items= line_items.reject(&driving?)
if new_order_history_enabled?
items = items.reject{ |li| li.expenses == 0 }
end
items
end
def driving?
proc { |line_item| LineItemType.new(line_item, segment).drive? }
end
Is there a one liner or a more cleaner way to write this?
Something like
items= line_items.reject { |li| li.driving? && ( new_order_history_enabled? && li.expenses == 0)}
Upvotes: 0
Views: 776
Reputation: 6156
Personally I don't think a one-liner is always cleaner, especially when it's a long one-liner. The style that (to me) is cleaner, is to write:
def fetch_items
items= line_items.reject(&:driving?)
items= items.reject(&:zero_expenses?) if new_order_history_enabled?
end
def driving?
proc { |line_item| LineItemType.new(line_item, segment).drive? }
end
# in the LineItem class, define the zero_expenses? method:
def zero_expenses?
expenses.zero?
end
Upvotes: 1
Reputation: 111
items= line_items.reject { |li| li.driving? || (new_order_history_enabled? && li.expenses == 0)}
Since you want both to apply here, I think you should use || instead of &&
That way, you are actually doing what you describe in your method. (and you only iterate once over the array, which is cool :) )
Although, and this is stylistic preference. I would prefer to do:
items = line_items.reject do |li|
li.driving? ||
(new_order_history_enabled? && li.expenses == 0)
end
since it might be clearer at a glance what we are doing
Upvotes: 3