简体   繁体   English

带有可选条件的 Array.select

[英]Array.select with optional conditionals

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.我想 select 一些基于可选参数的对象,比如params[:user_id]params[:start_date]params[:end_date]是否可选地从 controller 传递。 How do I include multiple conditionals within a single .select statement.如何在单个.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

wasn't working as intended.没有按预期工作。 The 2nd and 3rd conditional is ignored.第二个和第三个条件被忽略。

A pattern I like to use is next .我喜欢使用的模式是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.只需确保在最后添加一个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

you could of course change all these if.. else blocks to one liners if you prefer:如果您愿意,您当然可以将所有这些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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM