web-dev-qa-db-ja.com

Ruby .reject!と.delete_if

Rubyが初めてなので、.reject!との違いについて質問があります。ハッシュと配列を扱うときの.delete_ifメソッド。特定のオブジェクトを削除したいだけの場合、メソッド間に機能的な違いはありますか?そして、どちらを使うのか?

ありがとう!

[〜#〜] edit [〜#〜]ドキュメントを読みました...元の質問ではもっと明確だったはずです。効率の違いについてもっと考えていました。アイテムの削除方法は異なりますか? (繰り返しになりますが、戻り値は無視されます。違いがわかります。ありがとうございます!)

23
loganhasson

ドキュメント はこれについてかなり明確です。

違いは、reject!は配列を変更せず、nilを返します。 delete_ifは変更されていない配列を返します。

17
Explosion Pills
  • reject-一致する要素のない新しい配列を作成し、新しい配列を返します
  • delete_if-一致する要素をcurrent配列から削除し、配列を返します
  • reject!-一致する要素をcurrent配列から削除します。何かが拒否された場合は配列を返し、何も拒否されなかった場合はnilを返します。
44
Nowaker

tl; dr:delete_ifは少し速いようです。ただし、メソッドを選択する際の主な考慮事項は、他の回答で指摘されているように、戻り値の違いです。

あなたの質問は効率に関するものであることを明確にしたので、私はいくつかのテストを行いました:

> time { (1..100000).to_a.reject!{ |n| n % 5 == 0 } }
  0.390000   0.000000   0.390000 (  0.394596)
> time { (1..100000).to_a.delete_if{ |n| n % 5 == 0 } }
  0.400000   0.000000   0.400000 (  0.399122)

> time { (1..200000).to_a.reject!{ |n| n % 5 == 0 } }
  1.650000   0.000000   1.650000 (  1.657927)
> time { (1..200000).to_a.delete_if{ |n| n % 5 == 0 } }
  1.630000   0.010000   1.640000 (  1.637719)

> time { (1..300000).to_a.reject!{ |n| n % 5 == 0 } }
  3.700000   0.000000   3.700000 (  3.717206)
> time { (1..300000).to_a.delete_if{ |n| n % 5 == 0 } }
  3.660000   0.000000   3.660000 (  3.686213)

> time { (1..400000).to_a.reject!{ |n| n % 5 == 0 } }
  7.320000   0.020000   7.340000 (  7.361767)
> time { (1..400000).to_a.delete_if{ |n| n % 5 == 0 } }
  7.190000   0.020000   7.210000 (  7.239549)

だから、あるサイズを超えたように見えるdelete_ifは少し高速です。 timeは次のように定義されます:

def time(&block)
  puts Benchmark.measure(&block)
end

数値は、ユーザーのCPU時間、システムのCPU時間、ユーザーとシステムのCPU時間の合計、および経過したリアルタイムをそれぞれ表します。あなたは here の意味の説明を見つけることができます。すべてのベンチマークと同様に、YMMV、および5の倍数である数値を削除するという私が考案した例ではなく、特定のワークフローでテストする必要があることに注意してください。

4
dimid