Exclude option from .map collection in Ruby on Rails?

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 this would work, but it is not:

 <%= 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 doesn't work:

What am I doing wrong?

+8
ruby ruby-on-rails
source share
2 answers

map does not allow to skip values. You must first discard unwanted items.

 states.reject { |s| s.name == "excluded_state" }.map { |s| [s.name, s.id] } 

Another (more dirty) solution is to return nil for excluded elements and use Array#compact in the resulting array to remove these nil elements:

 states.map { |s| s.name == "excluded_state" ? nil : [s.name, s.id] }.compact 
+20
source share

Eureka's answer is good, but here is just a brief explanation to figure out what is going on.

map returns a new array with the results of block execution once for each element of the array. When you write [s.name, s.id] unless s.name == "excluded_state" , this forces the block to return nil when s.name == "excluded_state" that is, the result will be something like

 [["NY", 1], nil, ["CA", 2]] 

So, you can use reject to remove the unwanted state first, or simply use compact 1 to remove the nil entry as a result of your map , since you originally wrote it.


  • Array#compact returns a copy of the array with all nil elements removed.
+6
source share

All Articles