Comment obtenir le nombre total d'éléments dans un tableau, PAS le dernier identifiant?
Aucun des deux moyens que j'ai trouvés pour faire cela fonctionne:
my @a;
# Add some elements (no consecutive ids)
$a[0]= '1';
$a[5]= '2';
$a[23]= '3';
print $#a, "\n"; # Prints 23
print scalar(@a), "\n"; # Prints 24
Je m'attendais à en avoir 3 ...
Edit: Hash versus Array
Comme cincodenada l'a correctement souligné dans le commentaire, ysth a donné une meilleure réponse: j'aurais dû répondre à votre question par une autre question: "Voulez-vous vraiment utiliser un tableau Perl? Un hachage peut être plus approprié."
Un tableau alloue de la mémoire pour tous les indices possibles jusqu'au plus grand utilisé jusqu'à présent. Dans votre exemple, vous allouez 24 cellules (mais n'en utilisez que 3). En revanche, un hachage alloue uniquement de l'espace pour les champs qui sont réellement utilisés.
Solution de tableau: grep scalaire
Voici deux solutions possibles (voir ci-dessous pour l'explication):
print scalar(grep {defined $_} @a), "\n"; # prints 3
print scalar(grep $_, @a), "\n"; # prints 3
Explication: après avoir ajouté $a[23]
, votre tableau contient vraiment 24 éléments --- mais la plupart d'entre eux ne sont pas définis (ce qui est également évalué comme faux). Vous pouvez compter le nombre d'éléments définis (comme dans la première solution) ou le nombre d'éléments vrais (seconde solution).
Quelle est la différence? Si vous définissez $a[10]=0
, alors la première solution le comptera, mais pas la seconde (car 0 est faux mais défini). Si vous définissez $a[3]=undef
, aucune des solutions ne le comptera.
Solution de hachage (par yst)
Comme suggéré par une autre solution, vous pouvez travailler avec un hachage et éviter tous les problèmes:
$a{0} = 1;
$a{5} = 2;
$a{23} = 3;
print scalar(keys %a), "\n"; # prints 3
Cette solution compte les zéros et les valeurs non définies.
Il semble que vous souhaitiez un tableau clairsemé . Un tableau normal contiendrait 24 éléments, mais un tableau clairsemé en aurait 3. En Perl, nous émulons des tableaux clairsemés avec des hachages:
#!/usr/bin/Perl
use strict;
use warnings;
my %sparse;
@sparse{0, 5, 23} = (1 .. 3);
print "there are ", scalar keys %sparse, " items in the sparse array\n",
map { "\t$sparse{$_}\n" } sort { $a <=> $b } keys %sparse;
La fonction keys
dans un contexte scalaire renverra le nombre d'éléments dans le tableau fragmenté. Le seul inconvénient de l'utilisation d'un hachage pour émuler un tableau fragmenté est que vous devez trier les clés avant de les répéter si leur ordre est important.
Vous devez également vous rappeler d'utiliser la fonction delete
pour supprimer des éléments du tableau épars (il ne suffit pas de définir leur valeur sur undef).
Vous souhaitez peut-être un hachage à la place (ou en plus). Les tableaux sont un ensemble ordonné d'éléments; si vous créez $foo[23]
, vous créez implicitement $foo[0]
par $foo[22]
.
print grep scalaire {defini $ _} @a;
@people = qw( bob john linda );
$n = @people; # the number 3
Print " le number in the list is $n \n";
Les expressions en Perl renvoient toujours la valeur appropriée à leur contexte. Par exemple, que diriez-vous du "nom" * d'un tableau. Dans un contexte de liste, il donne la liste des éléments. Mais dans un contexte scalaire, il renvoie le nombre d'éléments dans le tableau:
sub uniq {
return keys %{{ map { $_ => 1 } @_ }};
}
my @my_array = ("a","a","b","b","c");
#print join(" ", @my_array), "\n";
my $a = join(" ", uniq(@my_array));
my @b = split(/ /,$a);
my $count = $#b;