web-dev-qa-db-fra.com

Ruby - teste le tableau

Quelle est la bonne façon de:

is_array("something") # => false         (or 1)

is_array(["something", "else"]) # => true  (or > 1)

ou pour obtenir le nombre d'articles dedans?

254
BuddyJoe

Vous voudrez probablement utiliser kind_of?().

>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
494
ry.

Êtes-vous sûr que a besoin d'être un tableau? Vous pourrez peut-être utiliser respond_to?(method) pour que votre code fonctionne avec des choses similaires qui ne sont pas nécessairement des tableaux (peut-être une autre chose énumberable). Si vous avez réellement besoin d'un array, la description décrivant la méthode Array#kind\_of? est la meilleure.

['hello'].respond_to?('each')
143
zgchurch

Au lieu de rechercher un Array,, convertissez simplement ce que vous obtenez en un Array, à un niveau, de sorte que votre code ne doit traiter que le cas.

t = [*something]     # or...
t = Array(something) # or...
def f *x
    ...
end

Ruby a plusieurs façons d'harmoniser une API pouvant prendre un objet ou un tableau d'objets. Vous devez donc deviner pourquoi vous voulez savoir si quelque chose est un tableau, j'ai une suggestion.

L'opérateur splat contient beaucoup de magie vous pouvez rechercher ou vous pouvez simplement appeler Array(something) qui ajoutera un wrapper Array si nécessaire. Cela ressemble à [*something] dans ce cas-là.

def f x
  p Array(x).inspect
  p [*x].inspect
end
f 1         # => "[1]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"

Vous pouvez également utiliser le splat dans la déclaration de paramètre, puis .flatten, ce qui vous donne un autre type de collecteur. (D'ailleurs, vous pouvez aussi appeler .flatten ci-dessus.)

def f *x
  p x.flatten.inspect
end         # => nil
f 1         # => "[1]"
f 1,2       # => "[1, 2]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"
f [1,2],3,4 # => "[1, 2, 3, 4]"

Et, merci gregschlom , il est parfois plus rapide d’utiliser simplement Array(x) car, lorsque c’est déjà un Array, il n’est pas nécessaire de créer un nouvel objet.

55
DigitalRoss

[1,2,3].is_a? Array est évalué à true.

19
dipole_moment

On dirait que vous recherchez quelque chose qui a un concept d’éléments. Je recommanderais donc de voir si c'est Enumerable. Cela garantit également l’existence de #count.

Par exemple,

[1,2,3].is_a? Enumerable
[1,2,3].count

notez que, alors que size, length et count fonctionnent tous pour les tableaux, count a la bonne signification ici - (par exemple, 'abc'.length et 'abc'.size _ les deux fonctionnent, mais 'abc'.count ne fonctionne pas comme ça).

Attention: une chaîne est_a? Enumerable, alors peut-être que ce n'est pas ce que vous voulez ... dépend de votre conception d'un tableau comme objet.

14
Peter

Essayer:

def is_array(a)
    a.class == Array
end

EDIT: L'autre réponse est bien meilleure que la mienne.

9
Lucas Jones

Pensez également à utiliser Array(). De la Ruby Community Style Guide :

Utilisez Array () au lieu de la vérification de tableau explicite ou [* var], lorsque vous utilisez une variable que vous souhaitez traiter en tant que tableau, mais vous n'êtes pas certain qu'il s'agisse d'un tableau.

# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }

# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }
6
GuyPaddock