/ / Drukowanie wartości skrótu tablic w perlu - tablice, perl, skrót, klucz

Drukowanie wartości dla mieszania tablic w perl - tablice, perl, hash, klucz

Mam skrót tablic, które są zadeklarowane w następujący sposób:

my %hash;
push @{ $hash{ $value1[$_] } }, [ $value1[$_], $value2[$_], $value3[$_], $value4[$_], $value5[$_] ] for 0 .. $#value1;

Chcę mieć możliwość sprawdzenia wartości dla każdego klucza za pomocą:

open KEYS, ">keys.txt" or die "Can"t write to "keys.txt"n";

for my $key ( sort keys %hash ) {
print KEYS "Key: $key contains the values: ";
for my $value ( @{$hash{$value1}} ) {
print KEYS "$value ";
}
print KEYS "n";
}
close(KEYS);

Chociaż mogę wizualizować klucze i powiązane wartości za pomocą Data :: Dumper, dane wyjściowe z powyższego kodu podają lokalizacje pamięci, a nie wartości dla każdego klucza. Na przykład:

Key: "Value1" contains the values: ARRAY(0x7fcd8645ba68)

Mimo że wypycham tę samą liczbę wartości do każdej tablicy, każdy klucz zawiera inną liczbę wartości

Czy jest coś nie tak ze sposobem, w jaki to robię?

Odpowiedzi:

6 dla odpowiedzi № 1

Po pierwsze, masz w swojej wewnętrznej pętli

for my $value ( @{$hash{$value1}} ) {
print KEYS "$value ";
}

Czym na ziemi jest $value1? Myślę, że chciałeś użyć $key. Zawsze use strict; use warnings ostrzegać przed niezdefiniowanymi wartościami i niezadeklarowanymi zmiennymi.

Następnie przyjrzyjmy się, co się stanie, kiedy to zrobimy

my %hash;
push @{ $hash{ $value1[$_] } }, "(value$_)" for 0 .. $#value1;

zamiast tego, tzn. po prostu wpychamy ciąg do tablicyref w haszu. Następnie wynik wygląda trochę jak

Key: Value1 contains the values: (value0)
Key: Value2 contains the values: (value1)
Key: Value3 contains the values: (value2)

Aha! Cokolwiek wpychamy na tę tablicę, jest drukowane tak, jak jest. Jeśli wypchniesz anonimową tablicę, np [...], otrzymasz oznaczenie tego odwołania: ARRAY(0x1234567).

Prawdopodobnie potrzebujesz zawartości tego arrayref. Łatwe: po prostu odłóż to.

...;
print KEYS "[@$value] ";

czy jakoś tak. The "[...]" są tutaj używane tylko do wizualnego grupowania wyników.


Uwagi do stylu:

Proszę rozważyć 3-arg open z leksykalnymi uchwytami plików:

my $filename = "keys.txt";
open my $keys, "<", $filename or die "Can"t open $filename: $!";

lub użyj automatycznej obsługi błędów:

use autodie;
open my $keys, "<", "keys.txt";

Tak czy inaczej, zwykle ważne jest, aby dołączyć powód za porażkę $! w komunikacie o błędzie lub jest prawie bezużyteczny.

Zamiast używać pętli, kod może być bardziej elegancki map i join, w zależności od gustu. Prawdopodobnie zapisałbym pętlę jako

use feature "say";
for my $key ( sort keys %hash ) {
say {$keys} "Key: $key contains the values: "
. join " ", map { "[@$_]" } @{ $hash{$key} };
}

3 dla odpowiedzi № 2

To dlatego, że wypychasz tablicę referencji zamiast listy wartości.

Porównać

push @array, [ $foo ];

do

push @array, $foo;

Obie @arrays zawierają pojedynczy element, ale pierwszy zawiera tablicę zawierającą $foo, podczas gdy ta ostatnia jest słuszna $foo.

Jeśli stracisz kwadratowe nawiasy klamrowe po pierwszym push argument, że będziesz dobrze iść.