おぴよの気まぐれ日記

おぴよの気まぐれ日記

岡山やプログラミング、ファッションのこと、子育てや人生、生き方についての備忘録。

【Ruby】配列の中身が重複しているかをチェックする方法(select、find)

csvのデータを取り込み別のcsvへ吐き出す処理をしていたのですが、値が重複していることに気がつきました。

こんな感じ。

data = []
inport = CSV.read("./inport.csv")
inport.each do |c|
  data << c
end

CSV.open("./export.csv", "w") do |export|
  data.each do |d|
    export << d
  end
end

この中で取り込んだデータが重複しているかどうかチェックする方法が分からず、グルグル回さないとダメなのかと思っていたのですが良い方法がありました。

> ff6 = [["Tina", 1],["Rokku", 2],["Edoga", 3],["Masshu", 4]]
=> [["Tina", 1], ["Rokku", 2], ["Edoga", 3], ["Masshu", 4]]

> ff6.select{|f| f[0] == "Masshu"}
=> [["Masshu", 4]]
irb(main):003:0>

selectを使うと合致したものだけを取ってきてくれます。 なので重複しているかチェックしたい場合は、sizeを使って数を調べてやれば良いです。

> ff6.select{|f| f[0] == "Masshu"}.size
=> 1

> if ff6.select{|f| f[0] == "Masshu"}.size > 0
>   # 処理
> end

めでたし、めでたし

追記

findを使った方が早いとのこと。

> ff6
=> [["Tina", 1], ["Rokku", 2], ["Edoga", 3], ["Masshu", 4]]

> ff6.find {|ff| ff[0] == "Masshu" }
=> ["Masshu", 4]

> ff6.find {|ff| ff[0] == "Masshu" }.size
=> 2

selectとの違いは、見つけた最初の配列を一つだけ返す。ってことですかね。 例えば、

# 「カイエン 4」を追加します
> ff6 = [["Tina", 1],["Rokku", 2],["Edoga", 3],["Masshu", 4], ["Kaien", 4]]
=> [["Tina", 1], ["Rokku", 2], ["Edoga", 3], ["Masshu", 4], ["Kaien", 4]]


# selectの場合
> ff6.select {|ff| ff[1] == 4 }
=> [["Masshu", 4], ["Kaien", 4]]

# findの場合
> ff6.find {|ff| ff[1] == 4 }
=> ["Masshu", 4]

最初に見つけた一つを返すんだから、そりゃー早いは。 今回やりたいことは、重複しているかのチェックだから1件でもあればNG。 ってことでfindを使うことにした。