Compruebe si la matriz no está vacía: ¿alguna?


¿Es malo comprobar si un array está no vacío usando el método any??

a = [1,2,3]

a.any?
=> true

a.clear

a.any?
=> false

O es mejor usar unless a.empty? ?

 150
Author: Andrew Grimm, 2011-06-06

6 answers

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 da el bloque, Ruby añade un bloque implícito de {/obj / obj} (que ¿hay alguna? devolverá true si al menos uno de los miembros de la colección no es falso o nulo).

 197
Author: Marcel Jackwerth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-05 21:21:03

La diferencia entre una matriz que evalúa sus valores a 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 usa para comprobar si el array contiene algo o no. Esto incluye cosas que evalúan a falso 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? viene del Enumerable módulo.
http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F

Se usa para evaluar si "cualquier" valor en la matriz se evalúa como verdadero. Métodos similares a esto no son ninguno? todos? y uno? donde todos ellos solo comprueban para ver cuántas veces true podría ser evaluado. 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
 62
Author: Polygon Pusher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-29 02:54:38

El prefijo de la instrucción con un signo de exclamación le permitirá saber si el array no está vacío. Así que en su caso -

a = [1,2,3]
!a.empty?
=> true
 24
Author: Denny Abraham Cheriyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-29 01:43:21

Evite any? para arreglos grandes.

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

any? no comprueba la longitud, pero en realidad escanea todo el array en busca de elementos truthy.

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 comprueba la longitud de la matriz única.

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 valores nil, como por ejemplo una matriz que se acaba de crear.

 15
Author: akuhn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-01 18:29:15

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ía o no. Si ' a ' está en blanco, el siguiente código no se ejecutará.

 4
Author: Dennis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 09:25:17

No creo que sea malo usar any? en absoluto. Lo uso mucho. Es claro y conciso.

Sin embargo, si usted está preocupado acerca de todos los valores nil tirándolo fuera, entonces usted está realmente preguntando si la matriz tiene size > 0. En ese caso, esta extensión simple muerta (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, preguntando lógicamente "¿tiene este objeto un tamaño?". Y es conciso, y no requiere ActiveSupport. Y es fácil de construir en.

Algunos extras para pensar:

  1. Esto no es lo mismo que present? de ActiveSupport.
  2. Es posible que desee una versión personalizada para String, que ignore los espacios en blanco (como lo hace present?).
  3. Es posible que desee el nombre length? para String u otros tipos donde podría ser más descriptivo.
  4. Es posible que lo desee personalizado para Integer y otros tipos Numeric, de modo que un cero lógico devuelva false.
 0
Author: lilole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-21 22:13:11