Ruby – test pour 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’objects qu’il contient?

Vous voulez probablement utiliser kind_of?() .

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

Etes-vous sûr qu’il doit s’agir d’un tableau? Vous pourrez peut-être utiliser la respond_to?(method) pour que votre code fonctionne pour des choses similaires qui ne sont pas nécessairement des tableaux (peut-être une autre chose enregistrable). Si vous avez réellement besoin d’un array , alors le post décrivant le Array#kind\_of? la méthode est la meilleure.

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

Au lieu de tester un Array, convertissez simplement ce que vous obtenez en un Array, un niveau Array, sorte que votre code ne doit gérer que le cas.

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

Ruby a plusieurs façons d’harmoniser une API qui peut prendre un object ou un tableau d’objects. Par conséquent, en supposant que vous voulez savoir si quelque chose est un tableau, j’ai une suggestion.

L’opérateur splat contient beaucoup de magie que vous pouvez rechercher, ou vous pouvez simplement appeler Array(something) qui appenda un wrapper Array si nécessaire. C’est similaire à [*something] dans ce cas.

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

Ou bien, vous pouvez utiliser le splat dans la déclaration de paramètre, puis .flatten , ce qui vous donnera 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 de simplement utiliser Array(x) car quand il s’agit déjà d’un Array il n’est pas nécessaire de créer un nouvel object.

On dirait que vous recherchez quelque chose qui a un concept d’éléments. Je recommande 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, même si size , length et count pour les tableaux, count est le bon sens ici (par exemple, 'abc'.length et 'abc'.size fonctionnent tous les deux, mais 'abc'.count ne fonctionne pas comme cette).

Attention: une chaîne est_a? Enumerable, alors peut-être que ce n’est pas ce que vous voulez … dépend de votre concept de tableau comme object.

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

Essayer:

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

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

Pensez également à utiliser Array() . Du guide de style communautaire Ruby :

Utilisez Array () au lieu de Array Check ou de [* var], lorsque vous traitez une variable que vous voulez traiter comme un 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) }