Voulez-vous un tableau réel, ou simplement quelque chose comme un tableau?
Kathy Van Stone,
1
Il n'y a pas de sécurité de type dans Ruby. Ne vous inquiétez pas que votre variable soit un tableau ou non. La méthode doit supposer que c'est le cas, et aller de l'avant et compter les appels dessus: my_array.count
user132447
Veuillez lire les réponses de zgchurch et DigitalRoss pour un Ruby plus idiomatique.
La vérification de type concerne Java. Allez-y et appelez simplement count sur la variable. Écrivez des tests unitaires pour vous assurer que la méthode fonctionne comme prévu.
user132447
14
@ user132447 en fait, java est sûr pour les types, vous n'avez donc pas à vous soucier de vérifier les types
grinch
8
J'ai rétrogradé cela maintenant car je ne pense pas que ce soit une bonne pratique dans une langue comme Ruby. La réponse de @zgchurch est clairement une approche beaucoup plus idiomatique de la question. Dans des cas comme celui-ci, je pense qu'il est beaucoup plus logique d'essayer de comprendre ce que signifie l'OP, plutôt que de lui donner aveuglément un fusil de chasse ...
Per Lundberg
1
Pourquoi voudriez-vous utiliser d' kind_of?()autres solutions? Des explications sur les avantages de votre réponse par rapport aux autres pourraient être utiles aux futurs lecteurs.
AlbertEngelB
148
Êtes-vous sûr qu'il doit s'agir d'un tableau? Vous pourrez peut-être l'utiliser 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 numérotable). Si vous en avez réellement besoin array, le message décrivant la Array#kind\_of?méthode est le meilleur.
Dans ce cas, je suis sûr que ce sera un tableau. Mais c'est bien de connaître cette méthode aussi. +1
BuddyJoe
Idée intéressante, j'utilise push / pop sur une structure de données. Est-ce que quelque chose en plus des tableaux répondrait à ces méthodes?
Drew
3
Si vous voulez quelque chose de plus semblable à un tableau, vous voudrez peut-être respond_to?(:to_ary).
Andrew Grimm
21
En général, c'est une bonne pratique pour le développement OO. J'ai lu où quelqu'un a dit essentiellement: n'imaginez pas que vous appelez des méthodes sur vos objets. Vous leur envoyez des messages. Si un objet sait comment répondre à votre message, peu importe de quelle classe il s'agit, s'il a une méthode nommée ça ou s'il crée dynamiquement une réponse via method_missing. L'important est de savoir s'il peut répondre à votre message? Cela permet une meilleure abstraction de la fonction et de la mise en œuvre. Vous pouvez changer quel objet vous utilisez plus tard, tant qu'il répond toujours correctement.
Nathan Long
2
Le seul problème avec cela est de dire que je veux vérifier si quelque chose est un itérable indexé, donc les tableaux, les listes chaînées, etc. seraient cool, mais je ne veux pas de magasins de valeurs clés comme les hachages?
Colton Voege
58
Au lieu de tester pour Array,simplement convertir tout ce que vous obtenez en un seul niveau Array,, votre code n'a besoin que de gérer le seul cas.
t =[*something]# or...
t =Array(something)# or...def f *x
...end
Ruby a différentes façons d'harmoniser une API qui peut prendre un objet ou un tableau d'objets, donc, devinez pourquoi 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)ce qui ajoutera un wrapper Array si nécessaire. C'est similaire à [*something]celui-ci.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1# => "[1]"
f [1]# => "[1]"
f [1,2]# => "[1, 2]"
Ou, vous pouvez utiliser le splat dans la déclaration de paramètres, puis .flattenvous donner un type de collecteur différent. (D'ailleurs, vous pouvez également appeler .flattenci - 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, grâce à gregschlom , il est parfois plus rapide de simplement l'utiliser Array(x)parce que quand c'est déjà un, Arrayil n'a pas besoin de créer un nouvel objet.
Qu'est-ce que cela ajoute aux réponses qui sont sur le site depuis près de sept ans ..?
Martin Tournoij
6
@Carpetsmoker il n'y a pas de réponse concise qui fait référence is_a?à tout ce fil. Le plus proche est a [1,2,3].is_a? Enumerable. Je pense toujours que cela vaut la peine d'avoir cette réponse.
dipole_moment
4
Vous savez .. vous avez en fait raison ... J'aurais juré avoir vu ça plus haut: - / Ayez un vote positif!
Martin Tournoij
16
Il semble que vous recherchiez quelque chose qui a un certain concept d'articles. Je recommanderais donc de voir si c'est le cas Enumerable. Cela garantit également l'existence de #count.
Par exemple,
[1,2,3].is_a?Enumerable[1,2,3].count
notez que, tandis que size, lengthet counttous fonctionnent pour les tableaux, countest le bon sens ici - (par exemple, 'abc'.lengthet les 'abc'.sizedeux fonctionnent, mais 'abc'.countne fonctionnent pas comme ça).
Attention: une chaîne is_a? Enumerable, alors peut-être que ce n'est pas ce que vous voulez ... dépend de votre concept d'un objet de type tableau.
Utilisez Array () au lieu de la vérification explicite du tableau ou [* var], lorsque vous traitez une variable que vous souhaitez 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)}
Cela produira des résultats inattendus lors du passage d'un Hash car to_aest appelé sur chaque argument ajouté au nouveau tableau, donc Array({id: 100})retourne[[:id, 100]]
Réponses:
Vous voulez probablement utiliser
kind_of()
.la source
is_a?
etinstance_of?
. Voir stackoverflow.com/questions/3893278/…kind_of?()
autres solutions? Des explications sur les avantages de votre réponse par rapport aux autres pourraient être utiles aux futurs lecteurs.Êtes-vous sûr qu'il doit s'agir d'un tableau? Vous pourrez peut-être l'utiliser
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 numérotable). Si vous en avez réellement besoinarray
, le message décrivant laArray#kind\_of?
méthode est le meilleur.la source
respond_to?(:to_ary)
.Au lieu de tester pour
Array,
simplement convertir tout ce que vous obtenez en un seul niveauArray,
, votre code n'a besoin que de gérer le seul cas.Ruby a différentes façons d'harmoniser une API qui peut prendre un objet ou un tableau d'objets, donc, devinez pourquoi 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)
ce qui ajoutera un wrapper Array si nécessaire. C'est similaire à[*something]
celui-ci.Ou, vous pouvez utiliser le splat dans la déclaration de paramètres, puis
.flatten
vous donner un type de collecteur différent. (D'ailleurs, vous pouvez également appeler.flatten
ci - dessus.)Et, grâce à gregschlom , il est parfois plus rapide de simplement l'utiliser
Array(x)
parce que quand c'est déjà un,Array
il n'a pas besoin de créer un nouvel objet.la source
[*nil] => []
. Vous pourriez donc vous retrouver avec un tableau vide.Array(foo)
est beaucoup plus efficace que[*foo]
[1,2,3].is_a? Array
évalue à vrai.la source
is_a?
à tout ce fil. Le plus proche est a[1,2,3].is_a? Enumerable
. Je pense toujours que cela vaut la peine d'avoir cette réponse.Il semble que vous recherchiez quelque chose qui a un certain concept d'articles. Je recommanderais donc de voir si c'est le cas
Enumerable
. Cela garantit également l'existence de#count
.Par exemple,
notez que, tandis que
size
,length
etcount
tous fonctionnent pour les tableaux,count
est le bon sens ici - (par exemple,'abc'.length
et les'abc'.size
deux fonctionnent, mais'abc'.count
ne fonctionnent pas comme ça).Attention: une chaîne is_a? Enumerable, alors peut-être que ce n'est pas ce que vous voulez ... dépend de votre concept d'un objet de type tableau.
la source
Essayer:
EDIT : L'autre réponse est bien meilleure que la mienne.
la source
Pensez également à utiliser
Array()
. Extrait du Ruby Community Style Guide :la source
to_a
est appelé sur chaque argument ajouté au nouveau tableau, doncArray({id: 100})
retourne[[:id, 100]]