PHP, pour toutes ses verrues, est assez bon sur ce plan. Il n'y a pas de différence entre un tableau et un hachage (peut-être que je suis naïf, mais cela me semble évidemment juste), et pour répéter soit vous faites simplement
foreach (array/hash as $key => $value)
Dans Ruby, il existe de nombreuses façons de faire ce genre de chose:
array.length.times do |i|
end
array.each
array.each_index
for i in array
Les hachages ont plus de sens, car j'utilise toujours
hash.each do |key, value|
Pourquoi ne puis-je pas faire cela pour les tableaux? Si je veux me souvenir d'une seule méthode, je suppose que je peux l'utiliser each_index
(car elle rend à la fois l'index et la valeur disponibles), mais c'est ennuyeux d'avoir à faire array[index]
au lieu de simplement value
.
Ah oui, j'ai oublié array.each_with_index
. Cependant, celui-ci est nul car il va |value, key|
et hash.each
vient |key, value|
! N'est-ce pas fou?
array#each_with_index
utilise|value, key|
parce que le nom de la méthode implique l'ordre, alors que l'ordre utilisé pourhash#each
imite lahash[key] = value
syntaxe?Réponses:
Cela va parcourir tous les éléments:
Tirages:
Cela va parcourir tous les éléments en vous donnant la valeur et l'index:
Tirages:
Je ne suis pas tout à fait sûr de votre question laquelle vous recherchez.
la source
Je pense qu'il n'y a pas qu'une seule bonne façon. Il existe de nombreuses façons différentes d'itérer, et chacune a sa propre niche.
each
est suffisant pour de nombreux usages, car je ne me soucie pas souvent des index.each_ with _index
agit comme Hash # chacun - vous obtenez la valeur et l'index.each_index
- juste les index. Je ne l'utilise pas souvent. Équivalent à "length.times".map
est une autre façon d'itérer, utile lorsque vous souhaitez transformer un tableau en un autre.select
est l'itérateur à utiliser lorsque vous souhaitez choisir un sous-ensemble.inject
est utile pour générer des sommes ou des produits, ou pour collecter un seul résultat.Cela peut sembler beaucoup de choses à retenir, mais ne vous inquiétez pas, vous pouvez vous en tirer sans les connaître toutes. Mais au fur et à mesure que vous commencez à apprendre et à utiliser les différentes méthodes, votre code deviendra plus propre et plus clair, et vous serez en route vers la maîtrise de Ruby.
la source
Je ne dis pas que
Array
->|value,index|
etHash
->|key,value|
n'est pas fou (voir le commentaire d'Horace Loeb), mais je dis qu'il y a une manière saine d'attendre cet arrangement.Lorsque je traite des tableaux, je me concentre sur les éléments du tableau (pas sur l'index car l'index est transitoire). La méthode est chacun avec index, c'est-à-dire chaque + index, ou | chaque, index |, ou
|value,index|
. Ceci est également cohérent avec l'index considéré comme un argument facultatif, par exemple | valeur | est équivalent à | value, index = nil | ce qui est cohérent avec | value, index |.Lorsque je traite des hachages, je suis souvent plus concentré sur les clés que sur les valeurs, et je traite généralement les clés et les valeurs dans cet ordre, soit
key => value
ouhash[key] = value
.Si vous voulez taper du canard, alors utilisez explicitement une méthode définie comme l'a montré Brent Longborough, ou une méthode implicite comme l'a montré maxhawkins.
Ruby est tout au sujet de l'adaptation de la langue au programmeur, pas du programmeur de l'adaptation à la langue. C'est pourquoi il y a tant de façons. Il y a tellement de façons de penser à quelque chose. Dans Ruby, vous choisissez le plus proche et le reste du code est généralement extrêmement soigné et concis.
Quant à la question d'origine, "Quelle est la" bonne "façon d'itérer à travers un tableau dans Ruby?", Eh bien, je pense que la façon principale (c'est-à-dire sans sucre syntaxique puissant ou puissance orientée objet) est de faire:
Mais Ruby est tout sur le sucre syntaxique puissant et la puissance orientée objet, mais de toute façon voici l'équivalent pour les hachages, et les clés peuvent être commandées ou non:
Donc, ma réponse est: "La" bonne "façon de parcourir un tableau dans Ruby dépend de vous (c'est-à-dire du programmeur ou de l'équipe de programmation) et du projet.". Le meilleur programmeur Ruby fait le meilleur choix (quelle puissance syntaxique et / ou quelle approche orientée objet). Le meilleur programmeur Ruby continue de chercher d'autres moyens.
Maintenant, je veux poser une autre question, "Quelle est la" bonne "façon de parcourir une plage en Ruby à l'envers?"! (Cette question est de savoir comment je suis arrivé sur cette page.)
C'est agréable à faire (pour les attaquants):
mais je n'aime pas faire (pour l'arrière):
Eh bien, cela ne me dérange pas vraiment de faire ça trop, mais quand j'enseigne à reculer, je veux montrer à mes élèves une symétrie sympa (c.-à-d. Avec une différence minimale, par exemple en ajoutant seulement un inverse ou un pas -1, mais sans modifier quoi que ce soit d'autre). Vous pouvez faire (pour la symétrie):
et
ce que je n'aime pas beaucoup, mais tu ne peux pas faire
Vous pourriez finalement faire
mais je veux enseigner du Ruby pur plutôt que des approches orientées objet (pour l'instant). Je voudrais répéter en arrière:
Je pense que cela est impossible sans définir une
pred
méthode, ce qui signifie modifier la classe Range pour l'utiliser. Si vous pouvez le faire, veuillez me le faire savoir, sinon une confirmation de l'impossibilité serait appréciée, mais ce serait décevant. Peut-être que Ruby 1.9 y répond.(Merci d'avoir pris le temps de lire ceci.)
la source
1.upto(10) do |i| puts i end
et10.downto(1) do puts i end
donne en quelque sorte la symétrie que vous vouliez. J'espère que cela pourra aider. Je ne sais pas si cela fonctionnerait pour les chaînes et autres.[*1..10].each{|i| puts "i=#{i}" }
.Utilisez each_with_index lorsque vous avez besoin des deux.
la source
Les autres réponses sont très bien, mais je voulais souligner une autre chose périphérique: les tableaux sont ordonnés, tandis que les hachages ne sont pas en 1.8. (Dans Ruby 1.9, les hachages sont ordonnés par ordre d'insertion des clés.) Il ne serait donc pas judicieux avant 1.9 d'itérer sur un hachage de la même manière / séquence que les tableaux, qui ont toujours eu un ordre défini. Je ne sais pas quel est l'ordre par défaut pour les tableaux associatifs PHP (apparemment, mon google fu n'est pas assez fort pour le comprendre non plus), mais je ne sais pas comment vous pouvez considérer les tableaux PHP réguliers et les tableaux associatifs PHP pour être "le même" dans ce contexte, car l'ordre des tableaux associatifs semble indéfini.
En tant que tel, la méthode Ruby me semble plus claire et intuitive. :)
la source
Essayer de faire la même chose de manière cohérente avec les tableaux et les hachages pourrait juste être une odeur de code, mais, au risque d'être considéré comme un demi-patcher codor, si vous recherchez un comportement cohérent, cela ferait-il l'affaire? ?:
la source
Voici les quatre options énumérées dans votre question, organisées par liberté de contrôle. Vous voudrez peut-être en utiliser un autre en fonction de vos besoins.
Passez simplement par des valeurs:
Parcourez simplement les indices:
Passer par les indices + variable d'index:
Nombre de boucles de contrôle + variable d'index:
la source
J'avais essayé de créer un menu (dans Camping et Markaby ) en utilisant un hachage.
Chaque élément a 2 éléments: une étiquette de menu et une URL , donc un hachage semblait correct, mais l'URL '/' pour 'Accueil' apparaissait toujours en dernier (comme vous vous y attendriez pour un hachage), donc les éléments de menu apparaissaient mal ordre.
L'utilisation d'un tableau avec
each_slice
fait le travail:Ajouter des valeurs supplémentaires pour chaque élément de menu (par exemple, comme un nom d' ID CSS ) signifie simplement augmenter la valeur de tranche. Donc, comme un hachage mais avec des groupes composés d'un certain nombre d'éléments. Parfait.
Donc, c'est juste pour dire merci d'avoir fait allusion par inadvertance à une solution!
Évident, mais mérite d'être mentionné: je suggère de vérifier si la longueur du tableau est divisible par la valeur de la tranche.
la source
Si vous utilisez le mixage énumérable (comme le fait Rails), vous pouvez faire quelque chose de similaire à l'extrait de php répertorié. Utilisez simplement la méthode each_slice et aplatissez le hachage.
Moins de patchs de singe requis.
Cependant, cela pose des problèmes lorsque vous avez un tableau récursif ou un hachage avec des valeurs de tableau. Dans ruby 1.9, ce problème est résolu avec un paramètre de la méthode d'aplatissement qui spécifie la profondeur de récurrence.
Quant à la question de savoir s'il s'agit d'une odeur de code, je ne suis pas sûr. Habituellement, lorsque je dois me pencher en arrière pour répéter quelque chose, je prends du recul et je réalise que j'attaque mal le problème.
la source
La bonne façon est celle avec laquelle vous vous sentez le plus à l'aise et qui fait ce que vous voulez qu'elle fasse. Dans la programmation, il y a rarement une façon «correcte» de faire les choses, plus souvent il y a plusieurs façons de choisir.
Si vous êtes à l'aise avec certaines façons de faire les choses, faites-le, à moins que cela ne fonctionne pas - alors il est temps de trouver une meilleure façon.
la source
Dans Ruby 2.1, la méthode each_with_index est supprimée. Au lieu de cela, vous pouvez utiliser each_index
Exemple:
produit:
la source
each_with_index
n'apparaît pas dans la documentation car elle est fournie par leEnumerable
module.Utiliser la même méthode pour itérer à travers les tableaux et les hachages est logique, par exemple pour traiter des structures de hachage et de tableaux imbriquées résultant souvent d'analyseurs, de la lecture de fichiers JSON, etc.
Une façon intelligente qui n'a pas encore été mentionnée est de savoir comment cela se fait dans la bibliothèque Ruby Facets d'extensions de bibliothèque standard. D' ici :
Il existe déjà
Hash#each_pair
un alias deHash#each
. Donc, après ce correctif, nous l'avons égalementArray#each_pair
et pouvons l'utiliser de manière interchangeable pour parcourir les hachages et les tableaux. Cela corrige la folie observée de l'OP quiArray#each_with_index
a les arguments de bloc inversés par rapport àHash#each
. Exemple d'utilisation:la source