检查数组是否为空:是吗?

时间:2011-06-05 21:16:46

标签: ruby arrays

使用any?方法检查数组是否为空是不是很糟糕?

a = [1,2,3]

a.any?
=> true

a.clear

a.any?
=> false

或者使用unless a.empty?更好吗?

6 个答案:

答案 0 :(得分:210)

在某些情况下,

any?not empty?不同。

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

来自文档:

  

如果没有给出块,Ruby补充道   {| obj |的隐式块obj}(那个   是什么?至少会返回true   其中一个收集成员不是   虚假或无。)

答案 1 :(得分:69)

将数值计算为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

用于评估数组中的“any”值是否为true。 类似的方法是没有?所有?还有一个?在那里他们都只是检查以确定可以评估多少次真实。这与数组中找到的值的数量无关。

案例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

答案 2 :(得分:27)

使用感叹号对语句进行前缀可以让您知道数组是否为空。所以在你的情况下 -

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

答案 3 :(得分:20)

对大型数组避免使用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值开头,例如刚刚创建的数组,则差异是相关的。

答案 4 :(得分:4)

我建议使用unlessblank检查是否为空。

示例:

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

这将知道&#39; a&#39;空的与否。 如果&#39; a&#39;为空,则以下代码不会运行。

答案 5 :(得分: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. 这与ActiveSupport中的present?不同。
  2. 您可能需要String的自定义版本,它会忽略空格(如present?所做的那样)。
  3. 您可能需要length?的名称String或其他可能更具描述性的类型。
  4. 您可能希望自定义Integer和其他Numeric类型,以便逻辑零返回false