yucatio@システムエンジニア

趣味で作ったものいろいろ

頭の体操[初級] 連続したフィールドの入力で、途中の未入力欄を検知 (Ruby編)

前回の記事の続きです。

yucatio.hatenablog.com

入力の途中で空欄があったらエラーメッセージを表示する機能を実装します。

f:id:yucatio:20160718141604p:plain

実装してみよう

サンプルとして、以下のようなメソッドを作成します。

  • 引数にStringの配列を受け取る
  • 配列の途中に空文字があり、その欄より後に空文字でない要素がある場合は、エラーメッセージを表示する。メッセージ中には何番目の要素がエラーかを表示する。

こんな動作イメージです

arr = ["佐藤", "鈴木", "高橋", "", "伊藤", "", "", "", "", ""]
detect_empty_field arr

# OUTPUT
# 4番目のフィールドが空です。値を入力してください。

簡単のために、以下を前提とします。

  • 引数で渡される配列はnilではない
  • 配列中の各要素はnilでない
  • 配列の各要素はString

この記事ではRubyで実装します。

実装は続きを読むをどうぞ

実装 その1

実装方針 その1

配列の各要素について、その要素が空文字かつ後方に空文字でない要素がある場合はエラーメッセージを出力します。

f:id:yucatio:20160723130648p:plain

def detect_empty_field(arr)

  arr[最初から最後の1つ前まで].each {
    if 配列の後方に空文字でない要素がある then
      "n番目の要素が空です" の出力
    end
  }

end

実装 その1

以下のように実装しました。javaよりはすっきりした印象です。

def detect_empty_field(arr)
  arr[0...-1].each_with_index {|val, i|
    next if val != ""

    if nil != arr[(i+1)..-1].index {|var| var != ""} then
      puts "#{i+1}番目のフィールドが空です。値を入力してください。"
    end
  }
end

実装 その2

実装方針 その2

実装方針その1では、配列を先頭から見ていきました。要素が空文字かつ配列の後方に空文字でない要素があればエラーとしました。 この方法でも正しく動作するのですが、同じ要素を何度も参照するのは効率悪いなと思ったので、別の方法を考えます。

配列を後ろから見ていって、初めに空でない要素が現れたときに、その配列のインデックスを保存しておきます。 そのあと、配列を前から見ていって、空文字であればエラーとします。

f:id:yucatio:20160723130654p:plain

def detect_empty_field(arr)
  空文字でない最後の配列のインデックスを取得
  arr[最初からインデックスの前まで].each {
    if 空でない要素 then
      "n番目の要素が空です" の出力
    end
  }
end

実装 その2

以下のように実装しました。javaより短くすっきり書けました。

def detect_empty_field(arr)
  last_non_empty = arr.rindex {|var| var != ""}

  return unless last_non_empty

  arr[0...last_non_empty].each_with_index {|val, i|
    if val == "" then
      puts "#{i+1}番目のフィールドが空です。値を入力してください。"
    end
  }
end

動作確認

コメントで出力結果を書いていきます。

arr = ["佐藤", "鈴木", "高橋", "田中", "伊藤", "渡辺", "山本", "中村", "小林", "加藤"]
detect_empty_field arr
# (出力なし)

arr = ["佐藤", "鈴木", "高橋", "田中", "", "", "", "", "", ""]
detect_empty_field arr
# (出力なし)

arr = ["佐藤", "", "", "", "", "", "", "", "", ""]
detect_empty_field arr
# (出力なし)

arr = ["", "", "", "", "", "", "", "", "", ""]
detect_empty_field arr
# (出力なし)

arr = ["佐藤", "鈴木", "高橋", "田中", "", "", "山本", "中村", "", ""]
detect_empty_field arr
# 5番目のフィールドが空です。値を入力してください。
# 6番目のフィールドが空です。値を入力してください。

arr = ["", "", "高橋", "田中", "", "", "山本", "中村", "", ""]
detect_empty_field arr
# 1番目のフィールドが空です。値を入力してください。
# 2番目のフィールドが空です。値を入力してください。
# 5番目のフィールドが空です。値を入力してください。
# 6番目のフィールドが空です。値を入力してください。

arr = ["", "", "", "", "", "", "", "", "", "加藤"]
detect_empty_field arr
# 1番目のフィールドが空です。値を入力してください。
# 2番目のフィールドが空です。値を入力してください。
# 3番目のフィールドが空です。値を入力してください。
# 4番目のフィールドが空です。値を入力してください。
# 5番目のフィールドが空です。値を入力してください。
# 6番目のフィールドが空です。値を入力してください。
# 7番目のフィールドが空です。値を入力してください。
# 8番目のフィールドが空です。値を入力してください。
# 9番目のフィールドが空です。値を入力してください。

うまく行きましたね。