I have a line like this:
<%= f.input :state_id, :input_html => {:value => (policy_address.state.name rescue nil)}, :required => true, :collection => states.map {|s| [ s.name, s.id] }, :include_blank => 'Please select'%>
I want to exclude a value from the states.map
collection. I thought that this would work but it doesn't:
<%= f.input :state_id, :input_html => {:value => (policy_address.state.name rescue nil)}, :required => true, :collection => states.map {|s| [ s.name, s.id] unless s.name == "excluded_state" }, :include_blank => 'Please select'%>
I put in unless s.name == "excluded_state
, but, again, it's not working:
What am I doing wrong?
map
doesn't allow to skip values. You have to reject unwanted elements first.
states.reject { |s| s.name == "excluded_state" }.map { |s| [s.name, s.id] }
Another (dirtier) solution is to return nil
for excluded elements and use Array#compact
on the resulting array to remove those nil
elements:
states.map { |s| s.name == "excluded_state" ? nil : [s.name, s.id] }.compact
Eureka's answer is good but here is just a brief explanation to clarify what's going on.
map
returns a new array with the results of running block once for every element in the array. When you write [s.name, s.id] unless s.name == "excluded_state"
this causes the block to return nil
when s.name == "excluded_state"
i.e. the result would be something like
[["NY", 1], nil, ["CA", 2]]
So you could use reject
to remove the unwanted state first, or you could just use compact
1 to remove the nil
entry on the result of your map
as you originally wrote it.
Array#compact
returns a copy of the array with all nil
elements removed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With