12

次のような行があります。

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

states.mapコレクションから値を除外したい。私はこれがうまくいくと思ったが、うまくいかない:

<%= 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たが、やはり動作しません:

私は何を間違っていますか?

4

3 に答える 3

26

map値をスキップすることはできません。最初に不要な要素を拒否する必要があります。

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

nil別の(より汚い)解決策は、除外された要素を返しArray#compact、結果の配列でそれらのnil要素を削除することです。

states.map { |s| s.name == "excluded_state" ? nil : [s.name, s.id] }.compact
于 2012-09-13T14:34:26.960 に答える
6

エウレカの答えは良いですが、ここでは何が起こっているのかを明確にするための簡単な説明です.

map配列内のすべての要素に対してブロックを 1 回実行した結果を含む新しい配列を返します。これを書くと、結果が次のようになるときに[s.name, s.id] unless s.name == "excluded_state"ブロックが返されますnils.name == "excluded_state"

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

したがってreject、最初に不要な状態を削除するために使用することも、最初に書いた結果のエントリを削除するためにcompact1を使用することもできます。nilmap


  1. Array#compactnilすべての要素が削除された配列のコピーを返します。
于 2012-09-13T14:38:09.803 に答える