web-dev-qa-db-fra.com

Vérifiez que le tableau n'est pas vide: aucun?

Est-il mauvais de vérifier si un tableau est non vide en utilisant la méthode any??

a = [1,2,3]

a.any?
=> true

a.clear

a.any?
=> false

Ou est-il préférable d'utiliser unless a.empty??

166
sivabudh

any? n'est pas identique à not empty? dans certains cas.

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

De la documentation:

Si le bloc n'est pas donné, Ruby ajoute un bloc implicite de {| obj | obj} (c'est-à-dire? retournera true si au moins un des membres de la collection n'est pas false ou nil).

221
Marcel Jackwerth

La différence entre un tableau évaluant ses valeurs à true ou s'il est vide.

La méthode empty? provient de la classe Array
http://Ruby-doc.org/core-2.0.0/Array.html#method-i-empty-3F

Il sert à vérifier si le tableau contient quelque chose ou non. Cela inclut les choses qui sont considérées comme fausses, telles que zéro et faux.

>> a = []
=> []
>> a.empty?
=> true
>> a = [nil, false]
=> [nil, false]
>> a.empty?
=> false
>> a = [nil]
=> [nil]
>> a.empty?
=> false

La méthode any? provient du module Enumerable.
http://Ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F

Il est utilisé pour évaluer si "toutes" les valeurs du tableau sont évaluées à true. Des méthodes similaires à ceci ne sont aucune? tout? et une? où ils vérifient tous combien de fois vrai pourrait être évalué. ce qui n'a rien à voir avec le nombre de valeurs trouvées dans un tableau.

cas 1

>> a = []
=> []
>> a.any?
=> false
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> true

cas 2

>> a = [nil, true]
=> [nil, true]
>> a.any?
=> true
>> a.one?
=> true
>> a.all?
=> false
>> a.none?
=> false

cas 3

>> a = [true, true]
=> [true, true]
>> a.any?
=> true
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> false
72
Polygon Pusher

Si vous préfixez l'instruction avec un point d'exclamation, vous saurez si le tableau n'est pas vide. Donc dans votre cas -

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

Evitez any? pour les tableaux de grande taille.

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

any? ne vérifie pas la longueur, mais analyse en réalité tout le tableau pour rechercher des éléments véridiques.

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? vérifie uniquement la longueur du tableau.

static VALUE
rb_ary_empty_p(VALUE ary)
{
  if (RARRAY_LEN(ary) == 0)
    return Qtrue;
  return Qfalse;
}

La différence est pertinente si vous avez des tableaux "clairsemés" qui commencent par beaucoup de valeurs nil, comme par exemple un tableau qui vient d'être créé.

22
akuhn

Je suggérerai d'utiliser unlesset blank pour vérifier si elle est vide ou non.

Exemple :

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

Cela saura "un" vide ou pas. Si 'a' est vide, le code ci-dessous ne fonctionnera pas.

4
Dennis

Je ne pense pas que ce soit mauvais d'utiliser any? du tout. Je l'utilise beaucoup. C'est clair et concis.

Cependant, si toutes les valeurs de nil vous préoccupent, alors vous demandez si le tableau contient size > 0. Dans ce cas, cette extension simple morte (PAS optimisée, à la manière de singe) vous rapprocherait.

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

Ceci est assez descriptif, demandant logiquement "cet objet a-t-il une taille?". Et c'est concis, et cela ne nécessite pas ActiveSupport. Et c'est facile à construire.

Quelques extras à considérer:

  1. Ce n'est pas la même chose que present? de ActiveSupport.
  2. Vous voudrez peut-être une version personnalisée pour String, qui ignore les espaces (comme present?.).
  3. Vous voudrez peut-être le nom length? pour String ou d'autres types où il pourrait être plus descriptif.
  4. Vous voudrez peut-être personnaliser cette option pour Integer et d’autres types Numeric, de sorte qu’un zéro logique renvoie false.
0
lilole