Si j'ai un hachage en Perl qui contient des mappages entiers complets et séquentiels (toutes les clés de 0 à n sont mappées sur quelque chose, aucune clé en dehors de cela), existe-t-il un moyen de convertir cela en tableau?
Je sais que je pourrais parcourir les paires clé/valeur et les placer dans un nouveau tableau, mais quelque chose me dit qu'il devrait y avoir un moyen intégré de le faire.
Si votre source de données d'origine est un hachage:
# first find the max key value, if you don't already know it:
use List::Util 'max';
my $maxkey = max keys %hash;
# get all the values, in order
my @array = @hash{0 .. $maxkey};
Ou si votre source de données d'origine est un hashref:
my $maxkey = max keys %$hashref;
my @array = @{$hashref}{0 .. $maxkey};
Ceci est facile à tester en utilisant cet exemple:
my %hash;
@hash{0 .. 9} = ('a' .. 'j');
# insert code from above, and then print the result...
use Data::Dumper;
print Dumper(\%hash);
print Dumper(\@array);
$VAR1 = {
'6' => 'g',
'3' => 'd',
'7' => 'h',
'9' => 'j',
'2' => 'c',
'8' => 'i',
'1' => 'b',
'4' => 'e',
'0' => 'a',
'5' => 'f'
};
$VAR1 = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j'
];
Vous pouvez extraire toutes les valeurs d'un hachage avec la fonction values
:
my @vals = values %hash;
Si vous les voulez dans un ordre particulier, vous pouvez alors placer les clés dans l’ordre souhaité, puis prendre un hash slice de cet ordre:
my @sorted_vals = @hash{sort { $a <=> $b } keys %hash};
OK, ce n'est pas très "intégré" mais ça marche. C'est aussi IMHO préférable à toute solution impliquant "trier" car c'est plus rapide.
map { $array[$_] = $hash{$_} } keys %hash; # Or use foreach instead of map
Sinon, moins efficace:
my @array = map { $hash{$_} } sort { $a<=>$b } keys %hash;
Perl ne fournit pas de solution intégrée pour résoudre votre problème.
Si vous savez que les touches couvrent une plage particulière 0..N
, vous pouvez en tirer parti:
my $n = keys(%hash) - 1;
my @keys_and_values = map { $_ => $hash{$_} } 0 .. $n;
my @just_values = @hash{0 .. $n};
Cela laissera les clés non définies dans %hashed_keys
comme undef
:
# if we're being nitpicky about when and how much memory
# is allocated for the array (for run-time optimization):
my @keys_arr = (undef) x scalar %hashed_keys;
@keys_arr[(keys %hashed_keys)] =
@hashed_keys{(keys %hashed_keys)};
Et si vous utilisez des références:
@{$keys_arr}[(keys %{$hashed_keys})] =
@{$hashed_keys}{(keys %{$hashed_keys})};
Ou, plus dangereusement, en supposant que ce que vous avez dit est vrai (ce n'est peut-être pas toujours vrai… dites simplement!):
@keys_arr = @hashed_keys{(sort {$a <=> $b} keys %hashed_keys)};
Mais c'est en quelque sorte à côté du point. Si elles ont été indexées pour commencer, pourquoi sont-elles dans un hachage maintenant?
$Hash_value =
{
'54' => 'abc',
'55' => 'def',
'56' => 'test',
};
while (my ($key,$value) = each %{$Hash_value})
{
print "\n $key > $value";
}
@a = @h{sort { $a <=> $b } keys %h};
Nous pouvons écrire un moment comme ci-dessous:
$j =0;
while(($a1,$b1)=each(%hash1)){
$arr[$j][0] = $a1;
($arr[$j][1],$arr[$j][2],$arr[$j][3],$arr[$j][4],$arr[$j][5],$arr[$j][6]) = values($b1);
$j++;
}
$ a1 contient la clé et $ b1 contient les valeursDans l'exemple ci-dessus, j'ai Hash of array et le tableau contient 6 éléments.
Comme l'a dit DVK, il n'y a pas de chemin intégré, mais cela fera l'affaire:
my @array = map {$hash{$_}} sort {$a <=> $b} keys %hash;
ou ca:
my @array;
keys %hash;
while (my ($k, $v) = each %hash) {
$array[$k] = $v
}
repère pour voir ce qui est plus rapide, je suppose que serait la seconde.
Un moyen facile est de faire @array = %hash
Par exemple,
my %hash = (
"0" => "zero",
"1" => "one",
"2" => "two",
"3" => "three",
"4" => "four",
"5" => "five",
"6" => "six",
"7" => "seven",
"8" => "eight",
"9" => "nine",
"10" => "ten",
);
my @array = %hash;
print "@array";
produirait la sortie suivante,
3 trois 9 neuf 5 cinq 8 huit 2 deux 4 quatre 1 un 10 dix 7 sept 0 zéro 6 six
La combinaison des réponses de FM et de Ether permet d’éviter de définir un scalaire par ailleurs inutile:
my @array = @hash{ 0 .. $#{[ keys %hash ]} };
La chose intéressante est que contrairement à l'approche scalar
, $#
fonctionne plus haut, même dans le cas peu probable où l'index par défaut du premier élément, $[
, n'est pas nul.
Bien sûr, cela voudrait dire écrire quelque chose de ridicule et d’obfusqué comme ceci:
my @array = @hash{ $[ .. $#{[ keys %hash ]} }; # Not recommended
Mais alors il y a toujours la chance remote que quelqu'un en ait besoin quelque part (wince) ...