Perl, convertir hash a array
arrays (11)
Como dijo DVK, no hay un camino construido, pero esto hará el truco:
my @array = map {$hash{$_}} sort {$a <=> $b} keys %hash;
o esto:
my @array;
keys %hash;
while (my ($k, $v) = each %hash) {
$array[$k] = $v
}
punto de referencia para ver cuál es más rápido, supongo que sería el segundo.
Si tengo un hash en Perl que contiene correlaciones de enteros completos y secuenciales (es decir, todas las claves de 0 a n están mapeadas en algo, no hay claves fuera de esto), ¿hay alguna forma de convertir esto en una matriz?
Sé que podría iterar sobre los pares clave / valor y colocarlos en una nueva matriz, pero algo me dice que debe haber un medio integrado para hacerlo.
Esto dejará las claves no definidas en %hashed_keys
como 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)};
Y, si estás usando referencias:
@{$keys_arr}[(keys %{$hashed_keys})] =
@{$hashed_keys}{(keys %{$hashed_keys})};
O, lo que es más peligroso, ya que asume que lo que dijiste es cierto (puede no ser siempre cierto ... ¡solo digo!):
@keys_arr = @hashed_keys{(sort {$a <=> $b} keys %hashed_keys)};
Pero esto es algo así como el punto. Si, para empezar, tenían un índice entero, ¿por qué están ahora en un hash?
La combinación de las respuestas de FM y Ether permite evitar la definición de un escalar innecesario:
my @array = @hash{ 0 .. $#{[ keys %hash ]} };
Lo bueno es que, a diferencia del enfoque scalar
, $#
funciona más arriba incluso en el caso improbable de que el índice predeterminado del primer elemento, $[
, no sea cero.
Por supuesto, eso significaría escribir algo tonto y ofuscado como ese:
my @array = @hash{ $[ .. $#{[ keys %hash ]} }; # Not recommended
Pero siempre existe la remota posibilidad de que alguien lo necesite en algún lugar ( mueca de dolor ) ...
OK, esto no está muy "integrado", pero funciona. También es IMHO preferible a cualquier solución que implique "ordenar", ya que es más rápido.
map { $array[$_] = $hash{$_} } keys %hash; # Or use foreach instead of map
De lo contrario, menos eficiente:
my @array = map { $hash{$_} } sort { $a<=>$b } keys %hash;
Perl no proporciona un built-in para resolver su problema.
Si sabe que las claves cubren un rango particular de 0..N
, puede aprovechar ese hecho:
my $n = keys(%hash) - 1;
my @keys_and_values = map { $_ => $hash{$_} } 0 .. $n;
my @just_values = @hash{0 .. $n};
Podemos escribir un tiempo como a continuación:
$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 contiene la clave y $ b1 contiene los valores En el ejemplo anterior, tengo Hash of array y la matriz contiene 6 elementos.
Puede extraer todos los valores de un hash con la función de values
:
my @vals = values %hash;
Si los quiere en un orden particular, puede colocar las claves en el orden deseado y luego tomar una porción hash de eso:
my @sorted_vals = @hash{sort { $a <=> $b } keys %hash};
Si su fuente de datos original es un hash:
# 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};
O si su fuente de datos original es un hashref:
my $maxkey = max keys %$hashref;
my @array = @{$hashref}{0 .. $maxkey};
Esto es fácil de probar usando este ejemplo:
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''
];
Una forma fácil es hacer @array = %hash
Por ejemplo,
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";
produciría la siguiente salida,
3 tres 9 nueve 5 cinco 8 ocho 2 dos 4 cuatro 1 uno 10 diez 7 siete 0 cero 6 seis
$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};