【发布时间】:2011-09-08 21:50:46
【问题描述】:
使用any?方法检查数组是否不为空是不是很糟糕?
a = [1,2,3]
a.any?
=> true
a.clear
a.any?
=> false
还是使用unless a.empty? 更好?
【问题讨论】:
使用any?方法检查数组是否不为空是不是很糟糕?
a = [1,2,3]
a.any?
=> true
a.clear
a.any?
=> false
还是使用unless a.empty? 更好?
【问题讨论】:
any? 在某些情况下与not empty? 不同。
>> [nil, 1].any?
=> true
>> [nil, nil].any?
=> false
来自文档:
如果没有给出块,Ruby 会添加 {|obj| 的隐式块obj}(那个 有吗?如果至少返回 true 集合成员之一不是 false 或 nil)。
【讨论】:
empty?相反的功能?
present? 方法。
#present? 仅适用于 Rails。在纯 Ruby 中,你会得到 NoMethodError: undefined method 'present?' for Array。
require 'activesupport'。
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?,它们都只是检查可以评估多少次 true。这与在数组中找到的值的计数无关。
案例一
>> 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
【讨论】:
避免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? 时,差异才是相关的,所以复杂度仍然是 O(1),就像 empty? 方法一样
在语句前加上感叹号会让你知道数组是否不为空。所以在你的情况下 -
a = [1,2,3]
!a.empty?
=> true
【讨论】:
我会建议使用unless和blank来检查是否为空。
例子:
unless a.blank?
a = "Is not empty"
end
这将知道“a”是否为空。 如果 'a' 为空,则下面的代码将不会运行。
【讨论】:
#blank? 是 Rails 的一部分。如果他们已经在使用 Rails,那么#present? 就是对#blank? 的否定。
我认为使用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。而且很容易构建。
需要考虑的一些额外内容:
present? 不同。String 的自定义版本,它会忽略空格(就像present? 一样)。length? 用于 String 或其他可能更具描述性的类型。Integer 和其他 Numeric 类型自定义它,以便逻辑零返回 false。【讨论】: