web-dev-qa-db-ja.com

配列を繰り返し処理しながらArray#deleteを使用するにはどうすればよいですか?

いくつかの要素を繰り返して削除したい配列があります。これは機能しません:

a = [1, 2, 3, 4, 5]
a.each do |x|
  next if x < 3
  a.delete x
  # do something with x
end
a #=> [1, 2, 4]

a[1, 2]にしたいです。どうすればこれを回避できますか?

65
Adrian

a.delete_if { |x| x >= 3 }

メソッドのドキュメントを参照してください こちら

更新:

ブロック内でxを処理できます。

a.delete_if do |element|
  if element >= 3
    do_something_with(element)
    true # Make sure the if statement returns true, so it gets marked for deletion
  end
end
114
Chubas

配列から削除する必要はありません。フィルタリングすることができます:

a = [1, 2, 3, 4, 5]

b = a.select {|x| x < 3}

puts b.inspect # => [1,2]

b.each {|i| puts i} # do something to each here
7
Joc

私は少し前にこの質問をしました。

Rubyでの反復中の削除?

Ruby=が何かを削除しようとすると.eachループを抜けるからです。配列から物を削除したい場合は、delete_ifは機能しますが、もっと制御したい、そのスレッドで私が持っている解決策はうまくいきますが、それはちょっといです。

3
Jesse Jashinsky

別の方法はreject!を使用することです。!があるため、「これは配列を変更します」という意味なので、間違いなく明確です。唯一の違いは、変更が行われなかった場合、reject!nilを返すことです。

a.delete_if {|x| x >= 3 }

または

a.reject! {|x| x >= 3 }

両方とも正常に動作します。

2
AlexChaffee