Πίνακες · Hashes

keys#

Απαριθμεί όλα τα κλειδιά ενός κατακερματισμού, ή όλους τους δείκτες ενός πίνακα.

Η keys είναι η πρωτογενής λειτουργία ενδοσκόπησης για συσχετιστικά και ευρετηριασμένα containers. Δοθέντος %HASH επιστρέφει τα κλειδιά του κατακερματισμού· δοθέντος @ARRAY (από την Perl 5.12 και μετά) επιστρέφει τους δείκτες του πίνακα 0 .. $#ARRAY. Η λίστα είναι αυτό που επαναλαμβάνετε, μετράτε, ταξινομείτε, ή τροφοδοτείτε σε άλλον τελεστή που καταναλώνει λίστα. Η keys είναι επίσης ο ιδιωματικός τρόπος να επαναφέρετε τον επαναλήπτη που διασχίζει η each.

Σύνοψη#

my @k = keys %h;
my @i = keys @a;
my $n = keys %h;        # scalar context: count
keys(%h) = 1000;        # preallocate buckets (hash only)

Τι επιστρέφεται#

Σε περιβάλλον λίστας, μια λίστα κάθε κλειδιού που είναι αυτή τη στιγμή στο %HASH, ή κάθε έγκυρου δείκτη του @ARRAY. Σε βαθμωτό περιβάλλον, την καταμέτρηση - χωρίς να κατασκευαστεί η λίστα - οπότε η scalar keys %h είναι ο φθηνός τρόπος για να ρωτήσετε «πόσες εγγραφές;»

Τα κλειδιά κατακερματισμού επιστρέφονται σε αυθαίρετη σειρά. Η σειρά είναι σταθερή για δεδομένο μη τροποποιημένο κατακερματισμό - οι keys, values και each τον διασχίζουν όλες στην ίδια ακολουθία - αλλά δεν είναι η σειρά εισαγωγής, δεν είναι ταξινομημένη, και σκόπιμα τυχαιοποιείται ανά κατακερματισμό για να αποτραπούν επιθέσεις αλγοριθμικής πολυπλοκότητας (βλέπε perlsec). Οποιαδήποτε εισαγωγή ή διαγραφή μπορεί να αναδιατάξει. Η μία τεκμηριωμένη εξαίρεση: η διαγραφή του κλειδιού που πιο πρόσφατα επέστρεψε η each ή η keys δεν διαταράσσει τη σειρά των υπολοίπων.

Οι δείκτες πίνακα, αντιθέτως, επιστρέφονται με το χαμηλότερο πρώτο: (0, 1, 2, …, $#ARRAY).

Τα επιστρεφόμενα κλειδιά κατακερματισμού είναι αντίγραφα. Η τροποποίηση ενός στοιχείου της επιστρεφόμενης λίστας δεν τροποποιεί τον κατακερματισμό. Συγκρίνετε με την values, που επιστρέφει ψευδώνυμα.

Καθολική κατάσταση που επηρεάζει#

  • Επαναλήπτης του %HASH / @ARRAY: η keys επαναφέρει τον εσωτερικό επαναλήπτη που μοιράζεται με τις each και values. Αυτή είναι η ιδιωματική επαναφορά - καλέστε keys %h σε κενό περιβάλλον ειδικά για να απορρίψετε οποιαδήποτε μερική διάσχιση της each:

    keys %h;                # reset iterator, no list built
    while (my ($k, $v) = each %h) { ... }
    

    Χωρίς αυτή την επαναφορά, μια προηγούμενη each που εξήλθε πρόωρα αφήνει τον επαναλήπτη στη μέση του κατακερματισμού και η επόμενη κλήση each συνεχίζει από εκεί.

Παραδείγματα#

Επαναλάβετε όλα τα κλειδιά σε αυθαίρετη σειρά:

my %h = (apple => 1, pear => 2, plum => 3);
for my $k (keys %h) {
    print "$k => $h{$k}\n";
}

Επαναλάβετε σε ντετερμινιστική σειρά περνώντας τα κλειδιά μέσα από τη sort:

for my $k (sort keys %h) {
    print "$k => $h{$k}\n";     # apple, pear, plum
}

Επαναλάβετε σε σειρά εισαγωγής παρακολουθώντας τα κλειδιά ξεχωριστά - οι ίδιοι οι κατακερματισμοί δεν θυμούνται τη σειρά εισαγωγής:

my %h;
my @order;
for my $pair (["apple", 1], ["pear", 2], ["plum", 3]) {
    my ($k, $v) = @$pair;
    push @order, $k unless exists $h{$k};
    $h{$k} = $v;
}
for my $k (@order) {
    print "$k => $h{$k}\n";     # apple, pear, plum (insertion)
}

Μετρήστε εγγραφές χωρίς να υλοποιήσετε τη λίστα:

my $n = keys %h;                # scalar context, O(1)
print "hash has $n entries\n";

Προεκχωρήστε buckets όταν γνωρίζετε ότι ο κατακερματισμός θα μεγαλώσει αρκετά. Η εκχώρηση είναι υπόδειξη μεγέθους, στρογγυλοποιημένη προς τα πάνω στην επόμενη δύναμη του δύο:

my %big;
keys(%big) = 10_000;            # allocates 16384 buckets
$big{$_} = 1 for 1 .. 10_000;   # no rehash churn during fill

Διασχίστε έναν πίνακα κατά δείκτη - χρήσιμο όταν χρειάζεστε τον δείκτη και το στοιχείο μαζί:

my @a = ("zero", "one", "two");
for my $i (keys @a) {
    print "$i: $a[$i]\n";
}

Ταξινομήστε έναν κατακερματισμό κατά τιμή, αριθμητικά φθίνουσα:

for my $k (sort { $h{$b} <=> $h{$a} } keys %h) {
    printf "%4d %s\n", $h{$k}, $k;
}

Οριακές περιπτώσεις#

  • Κενός κατακερματισμός ή πίνακας: επιστρέφει την κενή λίστα σε περιβάλλον λίστας, 0 σε βαθμωτό περιβάλλον. Καμία προειδοποίηση, καμία ειδική περίπτωση για παράκαμψη.

  • require v5.12 για πίνακες: η keys @array είναι συντακτικό σφάλμα σε perl παλαιότερες της 5.12. Βάλτε use v5.12; στην κορυφή αρχείων που χρησιμοποιούν τη μορφή για πίνακες αν έχει σημασία η φορητότητα σε αρχαιότερες perl.

  • Η σειρά κατακερματισμού δεν είναι αναπαραγώγιμη μεταξύ εκτελέσεων: η Perl τυχαιοποιεί τον σπόρο κατακερματισμού στην εκκίνηση. Μη χτίζετε ποτέ δοκιμή, κλειδί cache ή μορφή αρχείου που υποθέτει συγκεκριμένη σειρά keys %h. Ταξινομήστε αν χρειάζεστε ντετερμινισμό.

  • Η σειρά κατακερματισμού δεν είναι σταθερή μεταξύ εκδόσεων Perl: η τυχαιοποιημένη σειρά εντός μιας εκτέλεσης είναι σταθερή· ο ίδιος ο αλγόριθμος δεν εγγυάται μεταξύ εκδόσεων. Μη σειριοποιείτε την έξοδο της keys περιμένοντας να κάνει πλήρη κύκλο σε διαφορετική Perl.

  • Διαγραφή κατά τη διάρκεια επανάληψης: ασφαλής μόνο για το κλειδί που πιο πρόσφατα επέστρεψε η each ή η keys. Η διαγραφή διαφορετικού κλειδιού μπορεί να προκαλέσει διπλή επίσκεψη ή παράλειψη άλλων κλειδιών.

  • Η lvalue keys σε πίνακες είναι συντακτικό σφάλμα: το keys(@a) = 100 δεν είναι έγκυρο. Η μορφή προ-εκχώρησης buckets λειτουργεί μόνο σε κατακερματισμούς.

  • Η lvalue keys δεν μπορεί να συρρικνώσει: το keys(%h) = 10 σε κατακερματισμό που έχει ήδη 1024 buckets δεν έχει αποτέλεσμα. Το %h = () καθαρίζει τα περιεχόμενα αλλά διατηρεί τον αριθμό buckets· η undef %h ελευθερώνει τα buckets.

  • Κόστος μνήμης της μορφής λίστας: η keys %h σε περιβάλλον λίστας υλοποιεί κάθε κλειδί ως φρέσκο SV. Για κατακερματισμό ενός εκατομμυρίου εγγραφών αυτό αντιστοιχεί σε ένα εκατομμύριο εκχωρήσεις συν την επιστρεφόμενη λίστα. Επαναλάβετε με each ή while (my ($k, $v) = each %h) όταν θέλετε ροή πρόσβασης χωρίς την αιχμή μνήμης.

  • Tied κατακερματισμοί: αποστέλλουν μέσω FIRSTKEY / NEXTKEY. Η σειρά και οι παρενέργειες είναι ό,τι παρέχει η κλάση tie. Συγκεκριμένα, οι tied κατακερματισμοί μπορούν να αναδιαταχθούν κατά την εισαγωγή με τρόπους που δεν κάνουν οι συνηθισμένοι κατακερματισμοί, και μια tied keys μπορεί να είναι ακριβή αν το υποκείμενο αποθηκευτικό μέσο είναι απομακρυσμένο.

  • Βαθμωτό περιβάλλον σε tied κατακερματισμό: μπορεί να είναι ή να μην είναι O(1). Οι συνηθισμένοι κατακερματισμοί απαντούν στο scalar keys %h σε σταθερό χρόνο· μια κλάση tied πρέπει να υλοποιήσει ρητά το SCALAR για να αποφύγει πλήρη διάσχιση.

  • Η βαθμωτή keys σε πίνακα ισούται με scalar @array: και τα δύο επιστρέφουν τον αριθμό στοιχείων. Προτιμήστε το scalar @array για σαφήνεια, εκτός αν ο γύρω κώδικας είναι ήδη διατυπωμένος με όρους keys/values/each.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • values - η συνοδευτική λίστα των τιμών στην ίδια σειρά με την keys· επιστρέφει ψευδώνυμα, όχι αντίγραφα

  • each - διάσχιση ζεύγους (κλειδί, τιμή) με ροή που μοιράζεται τον ίδιο επαναλήπτη που επαναφέρει η keys

  • exists - δοκιμάστε αν ένα συγκεκριμένο κλειδί είναι παρόν χωρίς να κατασκευάσετε την πλήρη λίστα κλειδιών

  • delete - αφαιρέστε ένα κλειδί· ασφαλής στη μέση της επανάληψης μόνο για το πιο πρόσφατα επιστρεφόμενο κλειδί

  • sort - επιβάλετε ντετερμινιστική σειρά στην αυθαίρετη ακολουθία που επιστρέφει η keys

  • scalar - εξαναγκάστε βαθμωτό περιβάλλον για να λάβετε την καταμέτρηση χωρίς να υλοποιήσετε τη λίστα κλειδιών