写真のようにフォームに入力した値に重複があるのかを、保存前に確認する方法を見つけることができたので記録します。
ポジションは、f.selectを使用して、選択した値に対応する数字が、
選手名は、f.collection_selectを使用して、対応する選手ID(player.id)が送られるようにしています。
フォームから送られるparamsは、以下のようにタイトル、ポジション、名前が存在します。
(starting
,relief
,closer
は、対応する投手の選手IDが入っています。)
今回は、ポジション
と選手名
に重複がないかを確認します。
{"title"=>"サンプル1",
"one_position"=>"6", "one_name"=>"11",
"two_position"=>"4", "two_name"=>"11",
"three_position"=>"4", "three_name"=>"5",
"four_position"=>"5", "four_name"=>"14",
"five_position"=>"3", "five_name"=>"27",
"six_position"=>"7", "six_name"=>"12",
"seven_position"=>"9", "seven_name"=>"17",
"eight_position"=>"8", "eight_name"=>"3",
"nine_position"=>"2", "nine_name"=>"19",
"starting"=>"20", "relief"=>"21", "closer"=>"22"}
手順
1.処理しやすいようにポジション
と選手名
を別々の配列に振り分ける
・ 交互にポジションと選手名に振り分けたいが、starting
,relief
,closer
と連続で選手のIDが入っているので、一旦切り分ける
2.ポジションと選手名を分ける。
3.重複の確認
処理しやすいように分ける
field_player = params[:best_nine].values[1..-4] #タイトルと投手情報以外をいれる
pitcher = params[:best_nine].values[-3..-1] #投手の選手IDをいれる
ポジションと選手を分ける
-
each_slice(n)
で、n要素ずつブロックに渡してを繰り返す。 - ・野手のポジションと選手IDがブロックに渡される(
[[one_position, one_name],[two_position, two_name], ・・・]
) - ・ブロックの1つ目をポジション、最後(2つ目)を選手名として扱う
- ・Ruby 3.0.0 リファレンスマニュアル
-
player
には、投手の選手IDを追加する。 - ・配列に配列をpushで挿入すると、二重配列のような形になるので、
flatten
を用いて平坦化する
position = field_player.each_slice(2).map(&:first)
# field_player.each_slice(2).map {|n| n.first} と同じ処理
player = field_player.each_slice(2).map(&:last).push(pitcher)
player.flatten!
重複がないか確認
配列の要素の数と、配列内で重複していない要素の数の差が0でなければ、重複した値があると判定します。
if ((position.count - position.uniq.count) != 0 || (player.count - player.uniq.count) != 0)
全てのコード
field_player = params[:best_nine].values[1..-4]
pitcher = params[:best_nine].values[-3..-1]
position = field_player.each_slice(2).map(&:first).push(pitcher) # {|n| n.first}
position.flatten!
player = field_player.each_slice(2).map(&:last)
if ((position.count - position.uniq.count) != 0 || (player.count - player.uniq.count) != 0)
##参考記事
Ruby | 配列の奇数番目と偶数番目を取り出す方法
Ruby 3.0.0 リファレンスマニュアル (※each_slice)
Rubyで複数の配列を1つの配列に結合するために色々やってみた
重複した要素を取り除く