Check for array not empty: any?

后端 未结 6 1660
一整个雨季
一整个雨季 2020-12-12 11:32

Is it bad to check if an array is not empty by using any? method?

a = [1,2,3]

a.any?
=> true

a.clear

a.any?
=> false
<         


        
相关标签:
6条回答
  • 2020-12-12 11:58

    Prefixing the statement with an exclamation mark will let you know whether the array is not empty. So in your case -

    a = [1,2,3]
    !a.empty?
    => true
    
    0 讨论(0)
  • 2020-12-12 12:03

    The difference between an array evaluating its values to true or if its empty.

    The method empty? comes from the Array class
    http://ruby-doc.org/core-2.0.0/Array.html#method-i-empty-3F

    It's used to check if the array contains something or not. This includes things that evaluate to false, such as nil and false.

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

    The method any? comes from the Enumerable module.
    http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F

    It's used to evaluate if "any" value in the array evaluates to true. Similar methods to this are none?, all? and one?, where they all just check to see how many times true could be evaluated. which has nothing to do with the count of values found in a array.

    case 1

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

    case 2

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

    case 3

    >> a = [true, true]
    => [true, true]
    >> a.any?
    => true
    >> a.one?
    => false
    >> a.all?
    => true
    >> a.none?
    => false
    
    0 讨论(0)
  • 2020-12-12 12:04

    any? isn't the same as not empty? in some cases.

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

    From the documentation:

    If the block is not given, Ruby adds an implicit block of {|obj| obj} (that is any? will return true if at least one of the collection members is not false or nil).

    0 讨论(0)
  • 2020-12-12 12:15

    Avoid any? for large arrays.

    • any? is O(n)
    • empty? is O(1)

    any? does not check the length but actually scans the whole array for truthy elements.

    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? on the other hand checks the length of the array only.

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

    The difference is relevant if you have "sparse" arrays that start with lots of nil values, like for example an array that was just created.

    0 讨论(0)
  • 2020-12-12 12:18

    I'll suggest using unlessand blank to check is empty or not.

    Example :

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

    This will know 'a' empty or not. If 'a' is blank then the below code will not run.

    0 讨论(0)
  • 2020-12-12 12:19

    I don't think it's bad to use any? at all. I use it a lot. It's clear and concise.

    However if you are concerned about all nil values throwing it off, then you are really asking if the array has size > 0. In that case, this dead simple extension (NOT optimized, monkey-style) would get you close.

    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
    

    This is fairly descriptive, logically asking "does this object have a size?". And it's concise, and it doesn't require ActiveSupport. And it's easy to build on.

    Some extras to think about:

    1. This is not the same as present? from ActiveSupport.
    2. You might want a custom version for String, that ignores whitespace (like present? does).
    3. You might want the name length? for String or other types where it might be more descriptive.
    4. You might want it custom for Integer and other Numeric types, so that a logical zero returns false.
    0 讨论(0)
提交回复
热议问题