Czy istnieje sposób, aby uzyskać sub-hash? Czy muszę użyć skrótu mieszającego?Jak mogę uzyskać tylko część wartości skrótu w Perlu?
Na przykład:
%hash = (a => 1, b => 2, c => 3);
Chcę tylko
%hash = (a => 1, b => 2);
Czy istnieje sposób, aby uzyskać sub-hash? Czy muszę użyć skrótu mieszającego?Jak mogę uzyskać tylko część wartości skrótu w Perlu?
Na przykład:
%hash = (a => 1, b => 2, c => 3);
Chcę tylko
%hash = (a => 1, b => 2);
Hash slices zwraca wartości związane z listą kluczy. Aby dostać kawałek skrótu umożliwiającego zmianę sigil do @ i dostarczyć listę kluczy (w tym przypadku "a"
i "b"
):
my @items = @hash{"a", "b"};
Często można użyć operatora cytat słowo produkować listę:
my @items = @hash{qw/a b/};
można również przypisać do plasterka hash, więc jeśli chcesz nowy skrót, który zawiera podzbiór innego hash można powiedzieć
my %new_hash;
@new_hash{qw/a b/} = @hash{qw/a b/};
Wiele osób będzie korzystać z map zamiast kromki hash:
my %new_hash = map { $_ => $hash{$_} } qw/a b/;
Począwszy Perl 5.20.0, można dostać klucze i wartości w jednym etapie w przypadku korzystania z% sigil zamiast @ Sigil:
my %new_hash = %hash{qw/a b/};
to sprawia, że dlaczego "map" działa w/hashe trochę jaśniej dla mnie. Dzięki –
Larry Wall, brian d foy i ... Chas. Owens ... dziękuję za tak wyczerpujące wyjaśnienie! – bernie
Powinieneś prawdopodobnie uczynić go bardziej zrozumiałym, że segment mieszający ma tylko wartości, a nie pary klucz/wartość. – ysth
Hash jest nieuporządkowana pojemnik, ale kawałek termin tylko naprawdę ma sens pod względem uporządkowanej pojemniku. Może zajrzyj do tablicy. W przeciwnym razie możesz po prostu usunąć wszystkie elementy, których nie chcesz tworzyć "sub-hash".
W języku Perl plasterki skrótu są użyteczne i w pełni obsługiwane. Aby dowiedzieć się więcej przeczytaj ponownie [sekcja "Plasterki" w _perldata_] (http://perldoc.perl.org/perldata.html#Slices). –
Można by pewnie chcą zebrać listę kluczy chcesz:
my @keys = qw(a b);
a następnie użyć pętli, aby hash:
my %hash_slice;
for(@keys) {
$hash_slice{$_} = %hash{$_};
}
czyli
my %hash_slice = map { $_ => $hash{$_} } @keys;
(Moja preferencja to druga, ale ta, która Ci się podoba jest najlepsza.)
Zbyt wiele programowania funkcjonalnego prowadzi mnie najpierw do myślenia o numerze zip
.
Z List::MoreUtils zainstalowanego
use List::MoreUtils qw(zip);
%hash = qw(a 1 b 2 c 3);
@keys = qw(a b);
@values = @hash{@keys};
%hash = zip @keys, @values;
Niestety prototyp Lista :: MoreUtils na zip
hamuje
zip @keys, @hash{@keys};
Jeśli naprawdę chcesz, aby uniknąć zmienną pośrednią, można
zip @keys, @{[@hash{@keys}]};
Lub po prostu napisz własną zip
bez problematycznego prototypu. (To nie potrzebuje List :: MoreUtils w ogóle.)
sub zip {
my $max = -1;
$max < $#$_and $max = $#$_ for @_;
map { my $ix = $_; map $_->[$ix], @_; } 0..$max;
}
%hash = zip \@keys, [@hash{@keys}];
Jeśli masz zamiar być mutacji w miejscu,
%hash = qw(a 1 b 2 c 3);
%keep = map +($_ => 1), qw(a b);
$keep{$a} or delete $hash{$a} while ($a, $b) = each %hash;
unika dodatkowego kopiowania że rozwiązania map
i zip
ponieść. (. Tak, mutowania hash gdy jesteś iteracji nad nim jest bezpieczny ... tak długo, jak mutacja jest usuwanie tylko ostatnio iterowany parę)
Wyjaśnij to, proszę - '% keep = map + ($ _ => 1), qw (a b);'? –
FWIW używam Moose :: Autobox tutaj:
my $hash = { a => 1, b => 2, c => 3, d => 4 };
$hash->hslice([qw/a b/]) # { a => 1, b => 2 };
W prawdziwym życiu używam tego, aby wyodrębnić "nazwę użytkownika" i "hasło" z przesłanego formularza, i przekazać to do Catalyst $c->authenticate
(który oczekuje, w moim przypadku, hashref zawierający nazwę użytkownika i hasło, ale nic więcej).
Co to jest $ hash-> hslice (qw/a b /) lepsze niż @ {$ hash} {qw/a b /}? Czy jest to jeden z tych przypadków, w których, jeśli muszę prosić, jestem zbyt daleko, by to zrozumieć? –
Powinieneś mieć szablon odpowiedzi, aby "Używam łosia ::" było na początku każdej odpowiedzi. :) –
Chas. Owens: nie to robi hslice. @ {$ hash} {...} zwraca listę wartości; hslice zwraca nowe odwołanie do skrótu za pomocą obu kluczy i wartości. – jrockway
Jeszcze innym sposobem:
my @keys = qw(a b);
my %hash = (a => 1, b => 2, c => 3);
my %hash_copy;
@hash_copy{@keys} = @hash{@keys};
Nowy Perl 5.20 jest plastry cebulą powracający klucze, jak również wartości za pomocą% jak w ostatnim wierszu tutaj:
my %population = ('Norway',5000000,'Sweden',9600000,'Denmark',5500000);
my @slice_values = @population{'Norway','Sweden'}; # all perls can do this
my %slice_hash = %population{'Norway','Sweden'}; # perl >= 5.20 can do this!
Ponieważ nie ma nic logicznie "plaster" na podejrzewam, że coś ma wspólnego z "mapą". W tablicy można to zrobić na podstawie indeksu, ale w hasz nie ma wiarygodnej wewnętrznej reprezentacji danych w nim. Potrzebujesz pewnego rodzaju kwalifikatora (regex?), Aby zdefiniować, co powinno przejść do subhash, a co nie. –
BTW, twoja składnia hash jest nieprawidłowa: użyj nawiasów okrągłych "()" dla zwykłego skrótu, "{}" dla anonimowych odwołań hash. – trendels