Respuestas:
any?
No es lo mismo que not empty?
en algunos casos.
>> [nil, 1].any?
=> true
>> [nil, nil].any?
=> false
De la documentación:
Si no se proporciona el bloque, Ruby agrega un bloque implícito de {| obj | obj} (¿es cualquier? devolverá verdadero si al menos uno de los miembros de la colección no es falso o nulo).
present?
método de pago .
#present?
es solo para Rails. En puro Ruby obtendrás NoMethodError: undefined method 'present?' for Array
.
require 'activesupport'
.
true
o si está vacía.El método empty?
proviene de la clase Array
http://ruby-doc.org/core-2.0.0/Array.html#method-i-empty-3F
Se utiliza para verificar si la matriz contiene algo o no. Esto incluye cosas que evalúan a false
, como nil
y false
.
>> a = []
=> []
>> a.empty?
=> true
>> a = [nil, false]
=> [nil, false]
>> a.empty?
=> false
>> a = [nil]
=> [nil]
>> a.empty?
=> false
El método any?
proviene del módulo Enumerable.
http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F
Se utiliza para evaluar si "cualquier" valor en la matriz se evalúa true
. Métodos similares a esto son none?
, all?
y one?
, donde todos solo verifican para ver cuántas veces podría evaluarse la verdad. que no tiene nada que ver con el recuento de valores encontrados en una matriz.
caso 1
>> a = []
=> []
>> a.any?
=> false
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> true
caso 2
>> a = [nil, true]
=> [nil, true]
>> a.any?
=> true
>> a.one?
=> true
>> a.all?
=> false
>> a.none?
=> false
caso 3
>> a = [true, true]
=> [true, true]
>> a.any?
=> true
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> false
Prefijar la declaración con un signo de exclamación le permitirá saber si la matriz no está vacía. Entonces en tu caso ...
a = [1,2,3]
!a.empty?
=> true
Evitar any?
para grandes matrices.
any?
es O(n)
empty?
es O(1)
any?
no comprueba la longitud, pero en realidad escanea toda la matriz en busca de elementos verdaderos.
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?
por otro lado, solo verifica la longitud de la matriz.
static VALUE
rb_ary_empty_p(VALUE ary)
{
if (RARRAY_LEN(ary) == 0)
return Qtrue;
return Qfalse;
}
La diferencia es relevante si tiene matrices "dispersas" que comienzan con muchos nil
valores, como por ejemplo una matriz que acaba de crearse.
nil
valores, con matrices "normales" any?
sin retornos de bloque en el primer elemento, por lo que la complejidad sigue siendo O (1) como el empty?
método
Sugeriré usar unless
y blank
para comprobar si está vacío o no.
Ejemplo:
unless a.blank?
a = "Is not empty"
end
Esto sabrá 'a' vacío o no. Si 'a' está en blanco, el siguiente código no se ejecutará.
#blank?
Es parte de Rails. Si ya están usando Rails, #present?
es la negación de #blank?
todos modos.
No creo que sea malo usarlo any?
en absoluto. Lo uso mucho. Es claro y conciso.
Sin embargo, si le preocupa que todos los nil
valores lo descarten, entonces realmente está preguntando si la matriz lo ha hecho size > 0
. En ese caso, esta extensión simple (NO optimizada, estilo mono) te acercaría.
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
Esto es bastante descriptivo, lógicamente preguntando "¿este objeto tiene un tamaño?". Y es conciso, y no requiere ActiveSupport. Y es fácil de construir.
Algunos extras para pensar:
present?
de ActiveSupport.String
, que ignora los espacios en blanco (como lo present?
hace).length?
de String
u otros tipos donde podría ser más descriptivo.Integer
y otros Numeric
tipos, de modo que se devuelva un cero lógico false
.
empty?
?