keys#
מציג את כל המפתחות של האש, או את כל האינדקסים של מערך.
keys הוא הפרימיטיב לאינטרוספקציה של מכלים אסוציאטיביים ואינדקסיים. בהינתן %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בהקשר void במיוחד כדי להשליך כל סריקת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";
הקצאה מראש של דליים כאשר ידוע שההאש יגדל. ההשמה היא רמז גודל, מעוגל כלפי מעלה לחזקת השתיים הבאה:
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היא שגיאת תחביר ב־perls ישנים מ־5.12. יש לשיםuse v5.12;בראש קבצים המשתמשים בצורת המערך אם ניידות ל־perls עתיקים חשובה.סדר ההאש אינו ניתן לשחזור בין ריצות: Perl מערבלת את זרעי ההאש בעת ההפעלה. אין לבנות בדיקה, מפתח cache, או פורמט קובץ שמניח סדר מסוים של
keys %h. יש למיין אם נדרש דטרמיניזם.סדר ההאש אינו יציב בין גרסאות Perl: הסדר המעורבל בתוך ריצה יציב; האלגוריתם עצמו אינו מובטח בין מהדורות. אין לסריאליז את פלט
keysולצפות לנסיעה חזור על Perl אחר.מחיקה במהלך איטרציה: בטוחה רק עבור המפתח האחרון שהוחזר על־ידי
eachאוkeys. מחיקת מפתח אחר עלולה לגרום למפתחות אחרים להיות מבוקרים פעמיים או מדולגים.keysכ־lvalue על מערכים היא שגיאת תחביר:keys(@a) = 100אינה חוקית. צורת הקצאה־מראש־של־דליים עובדת על האשים בלבד.keysכ־lvalue אינה יכולה להקטין:keys(%h) = 10על האש שכבר יש לו 1024 דליים אינה משפיעה.%h = ()מנקה את התוכן אך משמרת את ספירת הדליים;undef %hמשחרר את הדליים.עלות זיכרון של צורת הרשימה:
keys %hבהקשר רשימה מחומר כל מפתח כ־SV רענן. עבור האש של מיליון רשומות זה מיליון הקצאות ועוד הרשימה המוחזרת. יש לעבור עםeachאוwhile (my ($k, $v) = each %h)כאשר נדרשת גישה הזרמתית בלי קפיצת הזיכרון.האשים קשורים: הדיספאץ« עובר דרך
FIRSTKEY/NEXTKEY. הסדר ותופעות הלוואי הם כל מה שמחלקת ה־tie מספקת. בפרט, האשים קשורים עלולים לערבב מחדש בהכנסה בדרכים שהאשים רגילים אינם, ו־keysקשור עלול להיות יקר אם האחסון התומך מרוחק.הקשר סקלר על האש קשור: עשוי להיות O(1) או לא. האשים רגילים עונים על
scalar keys %hבזמן קבוע; מחלקה קשורה חייבת לממשSCALARבמפורש כדי להימנע מסריקה מלאה.keysסקלרי על מערך שווה ל־scalar @array: שניהם מחזירים את ספירת האלמנטים. מומלץscalar @arrayלמען בהירות אלא אם הקוד הסובב כבר מנוסח במונחיkeys/values/each.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
values- רשימה משלימה של הערכים באותו סדר כמוkeys; מחזיר כינויים, לא עותקיםeach- סריקה הזרמתית של זוגות(מפתח, ערך)המשתפת את אותו איטרטור ש־keysמאפסexists- בדיקה האם מפתח מסוים נוכח בלי לבנות את רשימת המפתחות המלאהdelete- להסיר מפתח; בטוח באמצע איטרציה רק עבור המפתח האחרון שהוחזרsort- להטיל סדר דטרמיניסטי על הרצף השרירותי ש־keysמחזירscalar- לאלץ הקשר סקלר כדי לקבל את הספירה בלי לחומר את רשימת המפתחות