Le comte, la taille, la longueur...trop de choix en Ruby?
Je n'arrive pas à trouver une réponse définitive à ce sujet et je veux m'assurer de comprendre ce à le "n-ième niveau" 🙂
a = { "un" => "Bonjour", "b" => "Monde" } un.décompte # 2 un.taille # 2 un.longueur # 2 a = [ 10, 20 ] un.décompte # 2 un.taille # 2 un.longueur # 2
Afin de l'utiliser? Si je veux savoir si l'un a plus d'un élément, alors il ne semble pas à la matière, mais je veux m'assurer de comprendre la vraie différence. Cela s'applique à des tableaux trop. J'obtiens les mêmes résultats.
Aussi, je me rends compte que le comte/taille/longueur, ont des sens différents avec ActiveRecord. Je suis surtout intéressé à la pure Ruby (1.92) pour l'instant, mais si quelqu'un veut le carillon sur la différence AR fait que ce serait aussi bien appréciés.
Merci!
- Le phénomène que vous avez rencontré est parfois appelé TMTOWTDI: Il n'y a Plus d'Une Façon De le Faire. Ce slogan vient de la communauté Perl, Perl et est l'un de l'influence sur Ruby.
- ce sont généralement des alias pour les uns les autres, ils font la même chose. Il y a une méthode que vous devez garder à l'esprit:
Array#nitems
, qui retourne le nombre de non-NÉANT les éléments dans un tableau. Mais ce n'est pas disponible en Ruby 1.9 plus
Vous devez vous connecter pour publier un commentaire.
Pour les tableaux et les tables de hachage
taille
est un alias pourlength
. Ils sont synonymes et de faire exactement la même chose.count
est plus polyvalent - il peut prendre un élément ou d'un prédicat et de ne compter que ceux de ces éléments qui correspondent.Dans le cas où vous ne pas fournir un paramètre pour le comte, il a fondamentalement le même effet que l'appel de la longueur. Il peut y avoir une différence de performance si.
Nous pouvons voir à partir de la le code source pour le Tableau qu'ils ne sont presque exactement la même chose. Voici le code en C pour la mise en œuvre de
array.length
:Et voici la partie pertinente de la mise en œuvre de
array.count
:Le code pour
array.count
fait quelques contrôles supplémentaires, mais à la fin des appels exactement le même code:LONG2NUM(RARRAY_LEN(ary))
.Les hachages (le code source) d'autre part ne semblent pas mettre en place leur propre version optimisée de
count
de sorte que la mise en œuvre deEnumerable
(le code source) est utilisé, ce qui itère sur tous les éléments et les compte un par un.En général, je conseille d'utiliser
length
(ou son aliassize
) plutôt que decount
si vous voulez savoir combien il y a d'éléments tout à fait.Concernant ActiveRecord, d'autre part, il y sont des différences importantes. découvrez ce post:
Il y a une différence cruciale pour les applications qui font usage de connexions de base de données.
Lorsque vous êtes en utilisant de nombreuses Orm (ActiveRecord, DataMapper, etc.) la perception générale est que .la taille va générer une requête qui tous les articles de la base de données ('select * from matable') et de vous donner le nombre de postes, alors que .le comte va générer un seul query ('select count(*) from matable"), ce qui est considérablement plus rapide.
Parce que ces Formulaires sont si répandues que j'suivant le principe de moindre surprise. En général, si j'ai quelque chose dans la mémoire déjà, puis je utiliser .taille, et si mon code va générer une requête à une base de données (ou de service externe via une API) que j'utilise .le comte.
counter_cache
. Si vous avez une table,foo
, et il has_manybar
, vous aurez une colonne dansfoo
nommébars_count
est mise à jour à tout moment d'unbar
est créé ou détruit. À l'aide defoo.bars.size
est ce que vérifie que la colonne (sans l'interrogation de toutbars
).foo.bars.count
la requête réelle, ce qui irait à l'encontre de l'objet de la cache.Dans la plupart des cas (par exemple, Tableau ou Chaîne)
size
est un alias pourlength
.count
vient normalement à partir de Énumérable et peut prendre un prédicat facultatif bloc. Ainsienumerable.count {cond}
est [à peu près](enumerable.select {cond}).length
- il peut bien sûr contourner la structure intermédiaire qu'il a juste besoin de le comte de correspondance des prédicats.Note: je ne suis pas sûr si
count
forces une évaluation de l'énumération si le bloc n'est pas spécifié ou si elle les courts-circuits à lalength
si possible.Edit (et merci à Marc de réponse!):
count
sans bloc (au moins pour les Tableaux) ne pas la force d'une évaluation. Je suppose que sans mise comportement il est "ouvert" pour les autres implémentations, si forcer une évaluation sans un prédicat même jamais fait vraiment de sens de toute façon.J'ai trouvé une bonne answare à http://blog.hasmanythrough.com/2008/2/27/count-length-size
J'ai également une expérience personnelle:
Nous avons plusieurs façons de savoir combien d'éléments dans un tableau comme
.length
,.count
et.size
. Cependant, Il est préférable d'utiliserarray.size
plutôt quearray.count
. Parce que.size
est de mieux en matière de performance.L'ajout de plus pour Marquer Byers réponse. En Ruby, la méthode
array.size
est un alias pour Tableau#longueur méthode. Il n'y a pas de différence technique dans l'utilisation de ces deux méthodes. Peut-être que vous ne verrez pas de différence dans les performances. Cependant, laarray.count
aussi fait le même travail mais avec des fonctionnalités supplémentaires Tableau#comteIl peut être utilisé pour obtenir le nombre total des éléments basée sur une condition. Nombre peut être appelé en trois façons:
Tableau#comte # Renvoie le nombre d'éléments dans le Tableau
Tableau#comte n # Renvoie le nombre d'éléments ayant valeur de n dans la gamme
Tableau#count{|i| i.même?} Retourne le comte basée sur la condition appelée sur chaque élément de la matrice de
Ici toutes les trois méthodes de faire le même travail. Cependant c'est là où le
count
devient intéressant.Disons, je veux savoir combien d'éléments du tableau le tableau contient la valeur 2
Le tableau a un total de trois éléments dont la valeur est 2.
Maintenant, je veux trouver tous les éléments du tableau de plus de 4
Le tableau a un total de 6 éléments qui sont > de 4.
J'espère qu'il donne des informations sur
count
méthode.