Ответы:
any?
не такой, как not empty?
в некоторых случаях.
>> [nil, 1].any?
=> true
>> [nil, nil].any?
=> false
Из документации:
Если блок не задан, Ruby добавляет неявный блок {| obj | obj} (то есть any? вернет true, если хотя бы один из членов коллекции не равен false или nil).
present?
метод.
#present?
только для Rails. В чистом рубине вы получите 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
Он используется для оценки того, оценивается ли значение «any» в массиве 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
Перед префиксом оператора восклицательным знаком вы узнаете, не является ли массив пустым. Так что в вашем случае -
a = [1,2,3]
!a.empty?
=> true
Избегайте 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?
метод
Я предлагаю использовать unless
и blank
проверить пусто или нет.
Пример :
unless a.blank?
a = "Is not empty"
end
Это будет знать «пусто» или нет. Если «а» пусто, приведенный ниже код не будет работать.
#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?
из ActiveSupport.String
, которая игнорирует пробел (как present?
делает).length?
для String
или других типов, где оно может быть более наглядным.Integer
других Numeric
типов, чтобы возвращался логический ноль false
.
empty?
?