空でない配列を確認してください:ありますか?


189

メソッドを使用して配列が空でないかどうかを確認するのは悪いことany?ですか?

a = [1,2,3]

a.any?
=> true

a.clear

a.any?
=> false

それとも使用した方が良いunless a.empty?ですか?

回答:


246

any?not empty?一部のケースと同じではありません。

>> [nil, 1].any?
=> true
>> [nil, nil].any?
=> false

ドキュメントから:

ブロックが指定されていない場合、Rubyは{| obj |の暗黙のブロックを追加します obj}(つまり、any?は、コレクションメンバーの少なくとも1つがfalseまたはnilでない場合にtrueを返します)。


8
反対の機能はありますempty?か?
RocketR

12
@RocketRあなたはpresent?メソッドをチェックアウトしたいかもしれません。
dantheta

15
@dantastic #present?はRails専用です。純粋なRubyでは、あなたが取得しますNoMethodError: undefined method 'present?' for Array
RocketR

6
レールのみではなく、アクティブサポートはレールなしで使用できますrequire 'activesupport'
セルジオA.

82

値を評価する配列とtrue、空かどうかの違い。

このメソッドempty?は、Arrayクラスhttp://ruby-doc.org/core-2.0.0/Array.html#method-i-empty-3Fから
取得されます

配列に何かが含まれているかどうかを確認するために使用されます。これは、と評価さのものが含まfalseのような、nilとはfalse

>> a = []
=> []
>> a.empty?
=> true
>> a = [nil, false]
=> [nil, false]
>> a.empty?
=> false
>> a = [nil]
=> [nil]
>> a.empty?
=> false

このメソッドany?はEnumerableモジュールから来ています。
http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F

配列の「任意の」値がに評価されるかどうかを評価するために使用されtrueます。これに似たメソッドは、、none?all?ありone?、それらはすべて、真が何回評価されたかを確認するだけです。これは、配列で見つかった値の数とは関係ありません。

ケース1

>> a = []
=> []
>> a.any?
=> false
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> true

ケース2

>> a = [nil, true]
=> [nil, true]
>> a.any?
=> true
>> a.one?
=> true
>> a.all?
=> false
>> a.none?
=> false

ケース3

>> a = [true, true]
=> [true, true]
>> a.any?
=> true
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> false

31

ステートメントの前に感嘆符を付けると、配列が空でないかどうかがわかります。だからあなたの場合-

a = [1,2,3]
!a.empty?
=> true

27
二重否定?真剣ですか?
3lvis 2014

29
彼はそれほど深刻ではありません!
Alexander Bird、

5
へへ。二重否定は理想的ではなく、この特定のケースではより読みやすくなります。
デニーアブラハムシェリヤン2016年

11
二重否定は、元の質問「配列が空でないかどうかを確認する」の一部でした。これは質問に答えます。
mattfitzgerald

30

any?大きな配列は避けてください。

  • any? です O(n)
  • empty? です O(1)

any? 長さはチェックしませんが、実際に配列全体をスキャンして真の要素を探します。

static VALUE
rb_ary_any_p(VALUE ary)
{
  long i, len = RARRAY_LEN(ary);
  const VALUE *ptr = RARRAY_CONST_PTR(ary);

  if (!len) return Qfalse;
  if (!rb_block_given_p()) {
    for (i = 0; i < len; ++i) if (RTEST(ptr[i])) return Qtrue;
  }
  else {
    for (i = 0; i < RARRAY_LEN(ary); ++i) {
        if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
    }
  }
  return Qfalse;
}

empty? 一方、配列の長さのみをチェックします。

static VALUE
rb_ary_empty_p(VALUE ary)
{
  if (RARRAY_LEN(ary) == 0)
    return Qtrue;
  return Qfalse;
}

nilたとえば、作成されたばかりの配列など、多くの値で始まる「スパース」配列がある場合は、違いが関係します。


この使用例では、多くのnil値で始まる「スパース」配列があり、any?ブロックのない「通常」配列が最初の要素に戻る場合にのみ、違いが関係します。そのため、複雑さはempty?メソッドのようにO(1)のままです
Davidコスタ

4

とを使用してunlessblank空かどうかを確認することをお勧めします。

例:

unless a.blank?
  a = "Is not empty"
end

これは 'a'が空かどうかを知っています。「a」が空白の場合、以下のコードは実行されません。


4
#blank?Railsの一部です。彼らがすでにRailsを使用している場合#present?は、#blank?とにかく否定です。
Eva

0

使うのは悪くないと思いますany?。よく使っています。明確で簡潔です。

ただし、すべてのnil値がそれをスローすることに懸念がある場合は、配列にがあるかどうかを本当に質問していsize > 0ます。その場合、この完全に単純な拡張機能(最適化されていない、モンキースタイル)を使用すると、すぐに終了します。

Object.class_eval do

  def size?
    respond_to?(:size) && size > 0
  end

end

> "foo".size?
 => true
> "".size?
 => false
> " ".size?
 => true
> [].size?
 => false
> [11,22].size?
 => true
> [nil].size?
 => true

これはかなり説明的であり、論理的には「このオブジェクトにはサイズがあるか?」と質問します。そして、それは簡潔で、ActiveSupportを必要としません。そして、簡単に構築できます。

考慮すべきいくつかの追加事項:

  1. これはpresent?、ActiveSupport とは異なります。
  2. Stringように空白を無視するのカスタムバージョンが必要な場合present?があります。
  3. よりわかりやすい名前やその他のタイプの名前length?String必要になる場合があります。
  4. Integerやその他のNumeric型用にカスタム化して、論理値0が返されるようにすることもできますfalse
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.