2012-09-13 4 views
8

私はこのような行があります:私はstates.mapコレクションから値を除外したいRuby on Railsのcollection.mapからオプションを除外しますか?

<%= 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'%> 

を。私はこれが働くだろうと思ったが、それはしていません:

<%= 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'%> 

私はunless s.name == "excluded_stateに入れ、しかし、再び、それは働いていない:私は間違っ

何をしているのですか?

答えて

20

mapは値をスキップできません。まず、不要な要素を拒否しなければなりません。

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

別(汚れ)ソリューションは除外要素に対してnilを返し、それらのnilの要素を削除するために結果の配列にArray#compactを使用することです:

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

ありがとうございました!完璧に働いた – Ryan

+0

これは私が必要とするものです。ありがとう –

+4

'states.map {| s | [s.name、s.id] if s.name == "excluded_state"} .compact' –

6

Eureka's答えは良いのですが、ここだけの簡単な説明です何が起こっているのかを明らかにする。

mapは、のブロックを1回実行した結果を新しい配列に返します。配列内にはすべて要素があります。あなたが[s.name, s.id] unless s.name == "excluded_state"を書くときに、これはあなたが最初に不要な状態を削除するためにrejectを使用することができ、またはあなただけ削除するcompact を使用することができます

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

ようなものになるだろう結果すなわちnilときs.name == "excluded_state"を返すようにブロックを引き起こしあなたが最初に書いた通りmapの結果にnilのエントリがあります。


  1. Array#compact除去全てnil要素を持つ配列のコピーを返します。
+0

説明をいただきありがとうございます。なぜ私は私がしたことを試したときにエラーが発生していたのですか? – Ryan

+1

ありがとう:条件の順序は固定されています、私の精神分析者はこの1つで速すぎました;) – Eureka

関連する問題