Reputation: 145
I have an Array of Hashes
[
{ :user_id => 123,
:start_date => Date,
:end_date => Date
},
{ :user_id => 345,
:start_date => Date,
:end_date => Date
},
...
]
I want to select some of the objects based on optional parameters, say if params[:user_id]
, params[:start_date]
, params[:end_date]
is optionally passed from the controller. How do I include multiple conditionals within a single .select
statement.
Array.select do |arr|
arr[:user_id] == params[:user_id] if params[:user_id] &&
arr[:start_date] >= params[:start_date] if params[:start_date] &&
arr[:end_date] <= params[:end_date] if params[:end_date]
end
wasn't working as intended. The 2nd and 3rd conditional is ignored.
Upvotes: 0
Views: 1317
Reputation: 26758
A pattern I like to use is next
. This is basically a way to 'return early' from the block, and split up your conditions into multiple statements. Just make sure you add a true
at the end so that if the item passes all the validations, it will be included in the result.
result = array.select do |item|
if params[:user_id]
next if item[:user_id] != params[:user_id]
end
if params[:start_date]
next if item[:start_date] <= params[:start_date]
end
if params[:end_date]
next if item[:end_date] >= params[:end_date]
end
true
end
you could of course change all these if .. else
blocks to one liners if you prefer:
result = array.select do |item|
next if params[:user_id] && item[:user_id] != params[:user_id]
next if params[:start_date] && item[:start_date] <= params[:start_date]
next if params[:end_date] && item[:end_date] >= params[:end_date]
true
end
Upvotes: 1