Πίνακες

splice#

Αφαιρεί και/ή αντικαθιστά μια τομή ενός πίνακα επιτόπου, και επιστρέφει τα στοιχεία που αφαιρέθηκαν.

Η splice είναι ο χειρουργός γενικής χρήσης για πίνακες. Κάθε άλλος τροποποιητής πίνακα - οι push, pop, shift, unshift, ανάθεση μεμονωμένου στοιχείου - μπορεί να γραφτεί ως κλήση splice. Επιλέξτε τη θέση με το OFFSET, επιλέξτε πόσα στοιχεία να αποκόψετε με το LENGTH, και προαιρετικά παρέχετε μια LIST αντικαταστατών. Ο πίνακας μεγαλώνει ή συρρικνώνεται για να χωρέσει, και λαμβάνετε πίσω ό,τι αποκόπηκε.

Σύνοψη#

splice @array;                              # remove everything
splice @array, $offset;                     # remove from $offset to the end
splice @array, $offset, $length;            # remove $length elements
splice @array, $offset, $length, @list;     # remove and replace with @list

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

  • Περιβάλλον λίστας: η λίστα των στοιχείων που αφαιρέθηκαν, στην αρχική τους σειρά. Κενή λίστα αν δεν αφαιρέθηκε τίποτα.

  • Βαθμωτό περιβάλλον: το τελευταίο στοιχείο που αφαιρέθηκε, ή undef αν δεν αφαιρέθηκε τίποτα. Αυτό σπάνια είναι αυτό που θέλετε - καταφύγετε σε περιβάλλον λίστας εκτός αν χρειάζεστε ειδικά μόνο την ουρά.

  • Κενό περιβάλλον: τίποτα· χρησιμοποιήστε αυτή τη μορφή όταν σας ενδιαφέρει μόνο η επιτόπια τροποποίηση.

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

Βασική αφαίρεση - αποκοπή δύο στοιχείων ξεκινώντας από τη θέση 1:

my @a = ('a', 'b', 'c', 'd', 'e');
my @gone = splice @a, 1, 2;
# @a    == ('a', 'd', 'e')
# @gone == ('b', 'c')

Εισαγωγή χωρίς αφαίρεση - το LENGTH είναι 0, οπότε δεν βγαίνει τίποτα και η LIST εμβολιάζεται στο OFFSET:

my @a = (1, 2, 5, 6);
splice @a, 2, 0, 3, 4;
# @a == (1, 2, 3, 4, 5, 6)

Αντικατάσταση τμήματος - το LENGTH και το μέγεθος αντικατάστασης δεν χρειάζεται να ταιριάζουν. Εδώ τρία στοιχεία φεύγουν, ένα φτάνει:

my @a = ('x', 'y', 'z', 'w', 'v');
my @gone = splice @a, 1, 3, 'Y';
# @a    == ('x', 'Y', 'v')
# @gone == ('y', 'z', 'w')

Αφαίρεση της ουράς - παραλείψτε εντελώς το LENGTH για αποκοπή από το OFFSET μέχρι το τέλος:

my @a = (1, 2, 3, 4, 5);
my @tail = splice @a, 3;
# @a    == (1, 2, 3)
# @tail == (4, 5)

Αρνητικό OFFSET μετράει από το τέλος. Pop του τελευταίου στοιχείου:

my @a = ('a', 'b', 'c');
my $last = splice @a, -1;
# @a    == ('a', 'b')
# $last == 'c'

Κλασικό ιδίωμα - κατανάλωση ενός πίνακα $n στοιχεία τη φορά:

while (my @chunk = splice @queue, 0, $n) {
    process(@chunk);
}

Όλες οι συνηθισμένες πρωτογενείς λειτουργίες πίνακα γραμμένες ως splice (υποθέτοντας $#a >= $i):

push    @a, $x, $y;    #  splice @a, scalar(@a), 0, $x, $y
pop     @a;            #  splice @a, -1
shift   @a;            #  splice @a, 0, 1
unshift @a, $x, $y;    #  splice @a, 0, 0, $x, $y
$a[$i] = $y;           #  splice @a, $i, 1, $y

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

  • Αρνητικό OFFSET μετράει από το τέλος: το -1 είναι το τελευταίο στοιχείο, το -2 το προηγούμενο, και ούτω καθεξής. Αν το μέτρο υπερβαίνει το μήκος του πίνακα, η Perl εκπέμπει προειδοποίηση και περικόπτει στο 0.

  • Αρνητικό LENGTH αφήνει τόσα στοιχεία στο τέλος του πίνακα ανέπαφα. Η splice @a, 2, -1 αφαιρεί από τη θέση 2 μέχρι αλλά όχι συμπεριλαμβανομένου του τελευταίου στοιχείου.

  • OFFSET πέρα από το τέλος: με ρητό LENGTH, η Perl εκπέμπει προειδοποίηση και εμβολιάζει στο τέλος του πίνακα (ισοδύναμο με splice @a, scalar(@a), 0, LIST). Χωρίς LENGTH, δεν αφαιρείται τίποτα.

  • LENGTH πέρα από το τέλος: περικόπτεται σιωπηλά. Η splice @a, 1, 999 απλώς αφαιρεί τα πάντα από τη θέση 1 και μετά.

  • Παραλείπονται και το OFFSET και το LENGTH: αφαιρείται κάθε στοιχείο. Ο πίνακας μένει κενός.

  • Το μέγεθος της λίστας αντικατάστασης διαφέρει από το LENGTH: ο πίνακας μεγαλώνει ή συρρικνώνεται για να ταιριάξει. Δεν απαιτείται το scalar(@list) να ισούται με το LENGTH - αυτή η ασυμμετρία είναι όλο το νόημα της splice.

  • Αναφορά πίνακα: κάντε dereference inline. Οι splice @$ref, 0, 1 και splice @{ $obj->{items} }, -2 δουλεύουν και οι δύο.

  • Η splice σε τομή δεν υποστηρίζεται: η splice @a[1..3], 0, 1 είναι συντακτικό σφάλμα. Η splice απαιτεί κατονομασμένο πίνακα ή αποαναφερόμενο πίνακα, όχι έκφραση λίστας. Για να λειτουργήσετε σε εύρος, περάστε τα όρια ως OFFSET και LENGTH.

  • Το κενό περιβάλλον είναι εντάξει. Αν δεν χρειάζεται η τιμή επιστροφής, καλέστε την splice ως εντολή - σε αυτή την περίπτωση δεν γίνεται καμία εκχώρηση της λίστας αφαιρεμένων στοιχείων.

  • Βαθμωτές εκφράσεις ως πρώτο όρισμα: δεν επιτρέπονται. Ένα πειραματικό χαρακτηριστικό το επέτρεπε από την 5.14 έως την 5.22 και αφαιρέθηκε στην 5.24. Το πρώτο όρισμα πρέπει να είναι πίνακας (ή αποαναφερόμενο arrayref).

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

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

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

  • push - προσάρτηση στο τέλος· ισοδύναμο με splice @a, scalar(@a), 0, LIST

  • pop - αφαίρεση του τελευταίου στοιχείου· ισοδύναμο με splice @a, -1

  • shift - αφαίρεση του πρώτου στοιχείου· ισοδύναμο με splice @a, 0, 1

  • unshift - πρόθεμα στην αρχή· ισοδύναμο με splice @a, 0, 0, LIST

  • delete - επιφανειακά παρόμοιο αλλά σημασιολογικά διαφορετικό. Η delete $a[$i] αφήνει τρύπα (η θέση γίνεται undef) και δεν αναριθμεί τις μετέπειτα θέσεις· το μήκος του πίνακα δεν αλλάζει εκτός αν η διαγραμμένη θέση ήταν η τελευταία. Η splice @a, $i, 1 αφαιρεί φυσικά τη θέση και μετατοπίζει κάθε μετέπειτα στοιχείο μία θέση πίσω. Χρησιμοποιήστε delete για αραιούς πίνακες όπου η ταυτότητα της θέσης έχει σημασία· χρησιμοποιήστε splice όταν θέλετε ο πίνακας να κλείσει.

  • grep - φιλτράρει έναν πίνακα σε έναν νέο μέσω κατηγορήματος· καταφύγετε σε αυτό αντί για splice όταν θέλετε «κράτησε μόνο όσα ταιριάζουν» αντί για «κόψε ένα συνεχόμενο εύρος»