מערכים · האשים

values#

רישום כל ערך של האש (או כל אלמנט של מערך).

values הוא המקבילה בצד הערכים ל־keys. בהינתן האש, הוא מחזיר את כל הערכים; בהינתן מערך, הוא מחזיר את כל האלמנטים. האלמנטים חוזרים ככינויים לתוך המכל הבסיסי, כך שהצבה אליהם מתוך לולאה משנה את המכל במקום. כתופעת לוואי, קריאה ל־values מאפסת את האיטרטור ש־each, keys, ו־values חולקים עבור אותה האש או מערך.

תקציר#

my @v = values %hash;
my @v = values @array;
my $n = scalar values %hash;    # number of values
for (values %hash) { $_ *= 2 }  # mutate in place via aliasing

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

בהקשר רשימה: הרשימה המלאה של ערכים מהאש, או הרשימה המלאה של אלמנטים ממערך. רשומות מערך חוזרות בסדר אינדקסים (האינדקס הנמוך ביותר ראשון). רשומות האש חוזרות בסדר אקראי, פר־האש, המוגדר על־ידי המימוש - ראו מקרי קצה.

בהקשר סקלר: מספר הרשומות, זהה ל־scalar keys %h להאשים ול־scalar @a למערכים. values בהקשר void אינו עושה דבר נצפה למעט איפוס האיטרטור - זוהי הדרך האידיומטית לכפות איפוס איטרטור באמצע מעבר:

values %h;                       # void context: iterator reset only

הרשימה המוחזרת אינה עותק. כל אלמנט הוא כינוי לערך החי במכל. ה־aliasing הוא התנהגות מתועדת והוא הבסיס לאידיום של שינוי במקום תחת דוגמאות.

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

values מאפס את מצב האיטרטור פר־המכל ש־each קורא ומקדם. כל לולאת while (my ($k, $v) = each %h) { ... } בעיצומה על אותה האש תופעל מההתחלה בקריאה הבאה ל־each. ל־keys אותה השפעה. האיטרטור הוא תכונה של המכל, לא של אתר קריאה מסוים - לכן קורא בתת־שגרה אחת יכול להפריע ללולאת each שרצה בתת־שגרה אחרת אם הן פועלות על אותה האש.

דוגמאות#

מעבר על האש בסדר ממוין־לפי־מפתחות, ש־values לבדו אינו נותן לכם:

my %score = (alice => 90, bob => 75, carol => 82);
for my $k (sort keys %score) {
    print "$k: $score{$k}\n";
}

סכימה של כל ערך של האש:

use List::Util qw(sum0);
my %count = (apples => 3, pears => 5, plums => 2);
my $total = sum0 values %count;     # 10

שינוי של כל ערך במקום באמצעות הכינוי:

my %prices = (bread => 3.00, milk => 2.50, eggs => 4.20);
$_ *= 1.10 for values %prices;      # apply 10% price rise
# %prices is now (bread => 3.30, milk => 2.75, eggs => 4.62)

אותו אידיום עובד על מערך, אם כי עבור מערכים לולאת @array רגילה מקובלת יותר:

my @nums = (1, 2, 3, 4);
$_ **= 2 for values @nums;          # @nums is now (1, 4, 9, 16)

כפיית איפוס איטרטור each בעיצומו מבלי לצרוך את הפלט שלו:

while (my ($k, $v) = each %h) {
    last if $v > $threshold;
}
values %h;                          # void context: drop iterator state
# next each %h starts from the beginning

ספירת רשומות מבלי לבנות את הרשימה - הקשר סקלר אף פעם אינו מממש את הערכים:

if (scalar values %cache > 10_000) {
    prune(\%cache);
}

מקרי קצה#

  • ה־aliasing הוא התכונה וה־footgun. for (values %h) נותן לכם כינויים, לא עותקים. s/// הנראה תמים בתוך לולאה כזו משכתב את ההאש. אם רוצים עותקים, הציבו תחילה: my @v = values %h; for (@v) { ... }.

  • סדר ההאש מאוקרא. Perl 5.18+ מקרי את סדר המעבר פר־האש. שתי האשים שנבנו מאותם מפתחות יכולות להניב ערכים בסדרים שונים. אף פעם אל תסתמכו על הסדר לשום דבר שיוצא מהתהליך - סריאליזו דרך sort keys אם נחוצה יציבות.

  • הסדר יציב רק כל עוד ההאש לא משונה. הכנסות ומחיקות עשויות לבלבל את הסדר. החריג היחיד המתועד הוא מחיקת המפתח שהוחזר לאחרונה על־ידי each או keys, שמשאיר את הסדר הנותר ללא פגע.

  • keys, values, each מסכימים. עבור האש שלא שונה בין קריאות, keys %h ו־values %h מפיקים רשימות תואמות באותו סדר - (keys %h)[$i] ו־(values %h)[$i] מציינים את אותה הרשומה.

  • צורת המערך מתנהגת כמו @array בתוספת איפוס. values @a בהקשר רשימה שקול ל־@a, עם תופעת הלוואי של איפוס האיטרטור של המערך. עבור איפוס האיטרטור לבדו, keys @a בהקשר void הוא הבחירה המקובלת.

  • האש ריק או מערך ריק מחזיר את הרשימה הריקה בהקשר רשימה ו־0 בהקשר סקלר. ללא אזהרה, ללא שגיאה.

  • האשים מקושרים. ההתנהגות נמסרת למתודות FIRSTKEY / NEXTKEY / FETCH של מחלקת ה־tie. סמנטיקות הסדר, ה־aliasing, ואיפוס האיטרטור עוקבות אחרי כל מה שמימוש ה־tie מספק - הערבויות של ההאש הטהור לעיל אינן מועברות אוטומטית.

  • ניסוי שהוסר: ארגומנט סקלרי. Perl 5.14–5.22 קיבל ניסיונית values $ref; ניסוי זה הוסר ב־5.24. בצעו dereference מפורש: values %$ref, values @$ref.

  • תמיכת מערך דורשת 5.12+. הרצת values @a ב־Perl ישן יותר מעלה שגיאת תחביר. השתמשו ב־use v5.12; בראש קובץ שמסתמך על צורת המערך כדי להפוך את הדרישה למפורשת.

הבדלים מ־upstream#

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

ראו גם#

  • keys - המקבילה בצד המפתחות; אותם כללי סידור, אותו איטרטור, הקשר סקלר מחזיר את הספירה

  • each - איטרציה צעד־צעד המחזירה זוגות ($key, $value); חולקת את האיטרטור ש־values מאפס

  • exists - בדיקה אם מפתח נוכח מבלי להפעיל autovivification

  • delete - הסרת זוג מפתח/ערך; מחיקת המפתח שהוחזר לאחרונה על־ידי each או keys משאירה את סדר המעבר הנותר ללא פגע

  • map - שינוי צורה של ערכים לרשימה נגזרת מבלי לשנות את ההאש (החלופה ללא־aliasing ל־for (values %h))

  • sort - שלבו עם keys כאשר נחוץ סדר מעבר דטרמיניסטי