31

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

ありがとう!

編集 ドキュメントを読みました...元の質問でもっと明確にすべきだったと思います。私は効率の違いについてもっと疑問に思っていました。アイテムを削除する方法は異なりますか? (繰り返しますが、戻り値は無視します。違いがあることは理解しています。ありがとう!)

4

3 に答える 3

60
  • reject- 一致する要素を含まない新しい配列を作成し、新しい配列を返します
  • delete_if-現在の配列から一致する要素を削除し、配列を返します
  • reject!-現在の配列から一致する要素を削除します。何かが拒否された場合、または拒否されnilなかった場合は配列を返します。
于 2014-07-09T14:20:20.977 に答える
20

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

違いはreject!、配列を変更しない場合は を返すことnilです。 delete_if変更されていない配列を返します。

于 2013-09-20T16:48:31.043 に答える
5

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 時間とシステム CPU 時間の合計、および経過した実時間を表します。ここで、それらの意味の説明を見つけることができます。すべてのベンチマーク、YMMV と同様に、5 の倍数である数値を削除するという私の不自然な例ではなく、特定のワークフローでテストする必要があることに注意してください。

于 2016-02-21T13:46:28.660 に答える