Zakładając chcesz liczby w kolejności malejącej i tytuły wstępnego:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort { $b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title} }
@$pets;
To jest zwarty kod napisany w stylu funkcjonalnym. Aby to zrozumieć, spójrzmy na równoważny kod w bardziej znanym, imperatywnym stylu.
Operator Perla za sort
przyjmuje opcjonalny parametr SUBNAME, który pozwala na zoptymalizowanie porównania i nadanie mu nazwy opisującej to, co robi. Kiedy to robię, chciałbym zacząć sub nazwę od by_
, aby uczynić sort by_...
bardziej naturalną.
Aby rozpocząć, może masz napisane
sub by_count_then_title {
$b->{count} <=> $a->{count}
||
$a->{title} cmp $b->{title}
}
my @sorted = sort by_count_then_title @$pets;
Zauważ, że nie przecinek następuje SUBNAME w tej postaci!
Aby odpowiedzieć na pytanie innego komentatora, możesz użyć or
zamiast ||
w by_count_then_title
, jeśli uznasz, że jest bardziej czytelny. Zarówno <=>
, jak i cmp
have higher precedence (które można uważać za wiążące ściślej) niż ||
i or
, więc jest to ściśle kwestią stylu.
Aby wydrukować posortowaną tablicę, bardziej zaznajomieni wybór może być
foreach my $p (@sorted) {
print "$p->{count} $p->{title}\n";
}
Perl używa $_
jeśli nie określić zmienną, która pobiera każdą wartość, więc następujący ma takie samo znaczenie:
for (@sorted) {
print "$_->{count} $_->{title}\n";
}
for
i foreach
słowa kluczowe są synonimami, ale uważam, że powyższe zastosowania, tj, foreach
jeśli mam zamiar wymienić var W przeciwnym razie, odczytaj w sposób naturalny.
Korzystanie map
, bliski kuzyn foreach
, zamiast nie różni się zbytnio:
map print("$_->{count} $_->{title}\n"), @sorted;
Można również promować print
przez map
:
print map "$_->{count} $_->{title}\n",
@sorted;
koniec, aby uniknąć powtórzenia $_->{...}
, hash slice@$_{"count", "title"}
podaje wartości związane z liczbą i tytułem w bieżącym rekordzie pętli.Uwzględniając wartości, musimy join je z jednego miejsca i dołączyć do nowej linii do wyniku, więc
print map join(" ", @$_{qw/ count title /}) . "\n",
@sorted;
Pamiętaj, że qw//
jest skrótem pisząc listy ciągów. Jak pokazuje ten przykład, odczytaj wyrażenie z tylu do przodu (lub od dołu do góry w sposób, w jaki go wcięłam): najpierw sortuj rekordy, a następnie formatuj je, a następnie drukuj.
Można wyeliminować tymczasowe @sorted
ale nazwać imieniem porównania:
print map join(" ", @$_{qw/ count title /}) . "\n",
sort by_count_then_title
@$pets;
Jeżeli stosowanie join
jest po prostu zbyt rozwlekły do smaku, a następnie
print map "@$_{qw/ count title /}\n",
sort by_count_then_title
@$pets;
Co oznacza „map” oznaczać/zrobić w powyższym kodzie? I dlaczego nie musimy określać dwóch atrybutów w dwóch różnych zestawach nawiasów klamrowych? – syker
@syker: 'map' pobiera każdy skrót w posortowanej tablicy i wypisuje wartości' count' i 'title' na linii rozdzielonej spacjami. @ gbacon: Warto wyjaśnić, czy jest jakaś różnica między używaniem '||' i 'lub' w twoim sortowaniu, ponieważ zawsze widzę '||' w przykładach sortowania za cokolwiek. Czy istnieje możliwość, że bardziej czytelne "lub" zachowuje się inaczej w każdych okolicznościach? – Zaid
@syker @Zaid Zobacz zaktualizowaną odpowiedź. –