מערכים

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 אם דבר לא הוסר. זה לעתים נדירות מה שרוצים - פנו להקשר רשימה אלא אם נחוץ ספציפית רק הזנב.

  • הקשר void: שום דבר; השתמשו בצורה זו כאשר אכפת רק מהשינוי במקום.

דוגמאות#

הסרה בסיסית - חיתוך שני אלמנטים החל מאינדקס 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 שלילי נספר מהסוף. הוצאת האלמנט האחרון:

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 בסוף המערך (שקול ל־splice @a, scalar(@a), 0, LIST). ללא LENGTH, דבר אינו מוסר.

  • LENGTH מעבר לסוף: מהודק בשקט. splice @a, 1, 999 פשוט מסיר את הכל מאינדקס 1 והלאה.

  • גם OFFSET וגם LENGTH מושמטים: מסיר כל אלמנט. המערך נשאר ריק.

  • גודל רשימת ההחלפה שונה מ־LENGTH: המערך גדל או מתכווץ בהתאם. אין דרישה ש־scalar(@list) יהיה שווה ל־LENGTH - אי־הסימטריה הזו היא כל המטרה של splice.

  • הפניה למערך: בצעו dereference בתוך הקריאה. splice @$ref, 0, 1 ו־splice @{ $obj->{items} }, -2 שניהם עובדים.

  • ביצוע splice על פלח אינו נתמך: splice @a[1..3], 0, 1 הוא שגיאת תחביר. splice דורש מערך נקוב או מערך לאחר dereference, לא ביטוי רשימה. כדי לפעול על טווח, העבירו את הגבולות כ־OFFSET ו־LENGTH במקום זאת.

  • הקשר void בסדר. אם ערך ההחזרה אינו נחוץ, קראו ל־splice כהוראה - אין הקצאה של רשימת האלמנטים שהוסרו במקרה זה.

  • ביטויים סקלריים כארגומנט הראשון: אסור. תכונה ניסיונית התירה זאת מ־5.14 ועד 5.22 והוסרה ב־5.24. הארגומנט הראשון חייב להיות מערך (או arrayref לאחר dereference).

הבדלים מ־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 מסיר פיזית את החריץ ומסיט כל אלמנט מאוחר יותר למטה ב־1. השתמשו ב־delete למערכים דלילים שבהם זהות האינדקס חשובה; השתמשו ב־splice כשרוצים שהמערך ייסגר.

  • grep - סינון מערך לחדש לפי פרדיקט; פנו אליו במקום splice כשרוצים ״לשמור רק את אלה שמתאימים״ במקום ״לחתוך טווח רציף״