Array.select с необязательными условиями - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть массив хэшей

[
{ :user_id => 123,
  :start_date => Date,
  :end_date => Date
},
{ :user_id => 345,
  :start_date => Date,
  :end_date => Date
},
...
]

Я хочу выбрать некоторые объекты на основе необязательных параметров, скажем, если params[:user_id], params[:start_date], params[:end_date] необязательно передается из контроллера , Как включить несколько условных выражений в один оператор .select.

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

не работал должным образом. 2-е и 3-е условные игнорируются.

1 Ответ

1 голос
/ 07 апреля 2020

Шаблон, который мне нравится использовать, - next. По сути, это способ «вернуться рано» из блока и разделить ваши условия на несколько операторов. Просто убедитесь, что вы добавили true в конце, чтобы, если элемент прошел все проверки, он был включен в результат.

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

вы, конечно, можете изменить все эти if .. else блоки на один лайнер, если вы предпочитаете:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...