סקלרים ומחרוזות · רשימות

reverse#

היפוך רשימה - או, בהקשר סקלר, היפוך התווים של מחרוזת.

reverse הוא שני אופרטורים העונים לאותו השם. ההקשר מחליט איזה מהם תקבלו. בהקשר רשימה הוא מחזיר את LIST עם האלמנטים שלה בסדר ההפוך; ערכי האלמנטים אינם נוגעים בהם. בהקשר סקלר הוא משרשר את LIST למחרוזת אחת ומחזיר את המחרוזת ההיא עם התווים שלה הפוכים. הטעות הנפוצה של כתיבת my $s = reverse $str בציפייה לרשימה הפוכה (או כתיבת print reverse $str בציפייה למחרוזת הפוכה) היא המלכודת הגדולה ביותר של פונקציה זו - ראו מקרי קצה.

תקציר#

my @r    = reverse @arr          # list context: elements reversed
my $s    = reverse $str          # scalar context: characters reversed
my %inv  = reverse %h            # hash invert (value → key)
reverse                          # in scalar context, reverses $_

מה מקבלים בחזרה#

תלוי הקשר. האופרטור בוחן את הקשר הקורא שלו ומסתעף:

  • הקשר רשימה → רשימה חדשה עם האלמנטים של LIST בסדר הפוך. ערכי האלמנטים אינם מומרים למחרוזת, אינם משונים, אינם מועתקים ברמת התו. רשימה של הפניות נשארת רשימה של אותן הפניות.

  • הקשר סקלר → מחרוזת אחת: השרשור של האלמנטים של LIST לאחר המרה למחרוזת, כשכל התווים בסדר הפוך. תחת use utf8 / מחרוזות רחבות, ההיפוך הוא ברמת התווים, לא ברמת הבתים.

משמע שאותו אתר קריאה מחזיר צורות שונות באופן קיצוני בהתאם לאופן שבו משתמשים בו:

my @back  = reverse "abc", "def";    # ("def", "abc")
my $back  = reverse "abc", "def";    # "fedcba"

בשימוש ללא ארגומנטים בהקשר סקלר, reverse הופך את $_. בשימוש ללא ארגומנטים בהקשר רשימה, reverse מחזיר את הרשימה הריקה - לא $_ הפוך. print reverse; אינו מפיק פלט.

מצב גלובלי שהוא נוגע בו#

קורא את $_ כאשר נקרא ללא ארגומנטים בהקשר סקלר. זה הגלובלי היחיד שהוא נוגע בו. הוא אינו משנה את $_; הוא מחזיר את המחרוזת ההפוכה.

דוגמאות#

היפוך רשימה. האלמנטים עצמם אינם משתנים:

my @a = (1, 2, 3, 4, 5);
my @r = reverse @a;              # (5, 4, 3, 2, 1)

היפוך מחרוזת. כפו הקשר סקלר באמצעות scalar כאשר הביטוי הסובב היה אחרת רשימה:

my $s = reverse "Hello, world";  # "dlrow ,olleH"
print scalar reverse "Hello";    # "olleH"

מעבר על מערך לאחור מבלי לבנות מערך שני. reverse בכותרת הלולאה היא קריאה בהקשר רשימה; Perl צורך את הרשימה ההפוכה בעצלתיים ממכונת הלולאה:

my @stack = ("first", "second", "third");
for my $elem (reverse @stack) {
    print "$elem\n";             # third / second / first
}

מיון יורד. reverse sort הוא האידיום כאשר ההשוואה שלכם עולה ורוצים את ההיפך. לכל דבר מורכב יותר מהשוואת מחרוזות ברירת המחדל, החליפו את האופרנדים במשווה במקום זאת:

my @asc  = sort { $a <=> $b } @nums;
my @desc = reverse sort { $a <=> $b } @nums;     # works
my @desc2 = sort { $b <=> $a } @nums;            # preferred

היפוך האש. ערכים הופכים למפתחות, מפתחות הופכים לערכים:

my %by_name    = (alice => 1, bob => 2, carol => 3);
my %by_id      = reverse %by_name;               # (1 => "alice", ...)
print $by_id{2};                                 # "bob"

התעלול "dlrow ,olleH" - שימוש ב־reverse בהקשר סקלר כהיפוך־תווים חד־פעמי על משתנה מחרוזת:

my $word = "stressed";
my $rev  = scalar reverse $word;                  # "desserts"

מקרי קצה#

  • מלכודת #1: הקשר. my $s = reverse @arr אינו נותן לכם מערך הפוך; הוא נותן לכם את המחרוזת ההפוכה הנוצרת על־ידי שרשור אלמנטי המערך והיפוך כל תו. אם רוצים מערך הפוך מאוחסן דרך סקלר, השתמשו בהפניה: my $ref = [ reverse @arr ].

  • סקלר יחיד, הקשר שגוי. my @r = reverse $str מחזיר ($str) - רשימה בת אלמנט יחיד המכילה את $str ללא שינוי. אין מה לסדר מחדש. להיפוך התווים, כפו הקשר סקלר: my $r = reverse $str או my @r = (scalar reverse $str).

  • היפוך האש מאבד נתונים בערכים כפולים. reverse %h עובר על זוגות מפתח/ערך כרשימה שטוחה ובונה האש מחדש. אם שני מפתחות חולקים ערך, אחד מהם מנצח והשני מושלך בשקט; איזה מהם מנצח אינו מוגדר. בדקו ייחודיות תחילה אם זה משנה:

    my %seen;
    $seen{$_}++ for values %h;
    die "non-unique values" if grep { $_ > 1 } values %seen;
    my %inv = reverse %h;
    
  • ללא ארגומנטים בהקשר רשימה אינו עושה דבר מועיל. reverse ללא ארגומנטים מחזיר () בהקשר רשימה. ב־$_ מתייעצים רק בהקשר סקלר. print reverse; אינו מדפיס דבר; print scalar reverse; מדפיס את ההיפוך של $_.

  • ברמת התווים, לא ברמת הבתים. עבור מחרוזות של תווים רחבים, reverse הופך תווים, לא בתים. מחרוזת :utf8 של שלוש נקודות קוד נשארת שלוש נקודות קוד לאחר ההיפוך, ללא תלות ברוחבי הבתים שלהן. היפוך מחרוזת בתים גולמית עם תווים רב־בתיים שמעולם לא פוענחו, יפסיד אותה - פענחו תחילה.

  • הצבה־עצמית שומרת חורים. @a = reverse @a על מערך לא־קסום או tied מתנהג היטב, שומרת על אלמנטים שאינם קיימים במיקומיהם ההפוכים; מערך דליל נשאר דליל.

  • reverse sort אינו זהה ל־sort { $b cmp $a }. שניהם נותנים סדר יורד עבור השוואת ברירת המחדל היציבה, אך reverse sort מבצע שני מעברים על הנתונים ואיטי באופן מדיד ברשימות גדולות. העדיפו החלפת האופרנדים במשווה.

הבדלים מ־upstream#

תואם מלא ל־upstream Perl 5.42.

ראו גם#

  • sort - שלבו עם reverse לסדר יורד, או החליפו את $a/$b במשווה כדי להימנע מהמעבר השני

  • pop - הסרה מסוף מערך כאשר רוצים רק את האלמנט האחרון, לא את כל הרשימה הפוכה

  • shift - הסרה מהחזית; בשילוב עם עותק reverseed מתקבלת גישה דמוית־מחסנית לזנב המקורי

  • split - מייצר רשימה של תווים (עם //) או שדות שניתן אז לבצע עליהם reverse

  • join - השותף הטבעי כאשר הופכים רשימה של מחרוזות ורוצים מחרוזת אחת בחזרה

  • $_ - היעד המוגדר כברירת מחדל כאשר reverse נקרא ללא ארגומנטים בהקשר סקלר