מערכים של PowerShell, ArrayLists ואוספים: שיטות מיטביות

לעיתים קרובות בעת כתיבת סקריפטים בפוורשל, נדרשת דרך לאחסן סט של פריטים. דרך אחת נפוצה להשיג זאת היא עם מערך או סוג מסוים שנקרא ArrayList. אך מהו מערך בכלל? מערך הוא מבנה נתונים שמיועד לאחסון אוסף של פריטים. זה יכול לכלול פריטים שכאלה ושונים.

מערכים משמשים במגוון של שפות תכנות שונות ופוורשל אינו יוצא מן הכלל. ישנם מספר דרכים ליצירה, לניהול ולאופטימיזציה של מערכים. במאמר זה תלמד על ArrayLists, מערכים, ואוספים כמו גם מקומות מיטביים בהחילם בפוורשל.

דרישות מראש/נדרשים

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

  • פוורשל של Windows 3 או מאוחר יותר
  • פריימוורק .NET 4.5 או מאוחר יותר

רוצה עוד טיפים כמו אלו? בדוק את הבלוג האישי שלי בפוורשל בכתובת: https://nkasco.com/FriendsOfATA

יצירת מערכים עם פוורשל

ישנם מספר דרכים שונות ליצירת מערכים עם פוורשל. נניח שיש לך רשימת שמות שצריך לעבד באופן מסוים כמובן להלן.

John
Susie
Jim
Johnny
Carrie

בניית מערכים דרך פריטים מופרדים בפסיק

הדרך הבסיסית ביותר ליצירת מערך היא פשוט להקצות קלטים ידועים, מופרדים בפסיק, למשתנה כפי שמוצג למטה.

$BasicArray = "John", "Susie", "Jim", "Johnny", "Carrie"

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

PS51> $BasicArray.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     Object[]                                 System.Array

שימוש באופרטור Sub-Expression

באמצעות אופרטור Sub-Expression תוכל גם ליצור מערכים ב-PowerShell. המושג זה נפוץ כאשר לא ידוע כמה פריטים יתווספו למערך שלך. התוצאה יכולה לכלול אפס או רבים פריטים כאשר נוצרת.

שים לב למטה שנוצר מערך בשם $MyArray עם אפס אלמנטים בתוכו.

# יצירת מערך ריק עם אופרטור Sub-Expression
PS51> $MyArray = @()
PS51> $MyArray.count
0

שימוש באופרטור Range

מערכים אינם מוגבלים לאחסון מחרוזות כפי שנראה למעלה. תוכל גם ליצור מערכים עם סוגי אובייקטים אחרים כמו מספרים שלמים.

אם יש לך צורך במערך של מספרים שלמים בסדר סידורי, תוכל לקצShortcut ולהשתמש ב-אופרטור range ... למטה תראה מערך שנוצר עם המספרים 2 עד 5 בשורה אחת של קוד.

PS51> $NumberedArray = 2..5
PS51> $NumberedArray
2
3
4
5

יצירת אוסף ArrayList ב-PowerShell

שימוש ב-ArrayList ב-PowerShell הוא גם דרך לאחסן רשימה של פריטים בעזרת PowerShell. מחלקת ה-ArrayList היא חלק ממרחב השמות System.Collections ב-NET. על ידי יצירת אובייקט חדש מסוג זה, תוכל לאחסן אובייקטים בתוך ArrayList.

למטה תראה שיש ליצור באופן ברור אובייקט ArrayList באמצעות פקודת ה-cmdlet New-Object או על ידי המרה של מערך סטנדרטי לאובייקט ArrayList.

שים לב שבמקרה זה ה־BaseType הוא אובייקט כאשר בדוגמאות למעלה ה־BaseTypes היו של מערכים אשר מראים ירושה מהמחלקה Object. לבסוף, PowerShell מספק גישה למערכת הסוגים של .NET.

PS51> $MyArrayList = New-Object -TypeName "System.Collections.ArrayList"
# להמיר מערך ל־ArrayList הוא אפשרות תקפה גם כן
PS51> $MyArrayList = [System.Collections.ArrayList]@()
PS51> $MyArrayList.GetType()

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     True     ArrayList                                System.Object

הוספת פריטים למערך

כאשר אתה יוצר מערך, תוכל להגדיר את כל האלמנטים בזמן היצירה או להוסיף אותם אד-הוק.

כדי להוסיף אלמנטים לאוסף קיים, תוכל להשתמש באופרטור += או בשיטת Add. אך ידעו שישנן הבדלים ניכרים בדרך בהם הם פועלים.

כאשר אתה יוצר מערך סטנדרטי עם @(), תשתמש באופרטור +=, אך כדי להוסיף אלמנטים ל־ArrayList, תשתמש בשיטת Add. שיטות אלו שונות בכך שאופרטור += מ־משמיד את המערך הקיים ויוצר מערך חדש עם הפריט החדש.

כדי להדגים, תראה מטה שתוכל להתייחס למאפיין IsFixedSize עבור מערך או ArrayList כדי לדעת איזה מהם הוא לא ניתן לשינוי ואיזה לא.

PS51> $BasicArray.IsFixedSize
True

PS51> $MyArrayList.IsFixedSize
False

מאחר שמערך בסיסי הוא אוסף בגודל קבוע, אין באפשרותך לשנות אותו.

ניסיון להשתמש בשיטת Add() עם מערך בגודל קבוע יגרום לשגיאה עקב הגודל הקבוע. למטה ניתן לראות כמה דוגמאות שבהן ניתן להוסיף פריטים בהצלחה למערך.

#לא עובד
$BasicArray.Add("Nate")

#עובד
$BasicArray += "Nate"
$MyArrayList.Add("Nate")
$MyArrayList += "Nate"

הסרת פריטים ממערך

עכשיו שיש לך הבנה טובה יותר כיצד להוסיף פריטים למערך, בוא נכסה כמה דרכים שבהן תוכל להסיר פריטים ממערך.

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

$NewBasicArray = $BasicArray -ne "Nate"

מאחר ו-ArrayList אינו קבוע, תוכל להסיר איברים ממנו באמצעות שיטת Remove(). זו סצנה אחת בה שימוש ב-ArrayList עשוי להועיל אם תתכוון להוסיף/להסיר פריטים בתדירות.

$MyArrayList.Remove("Nate")

אחזור פריטים ספציפיים ממערך או מ-ArrayList

כדי לאחזר פריטים ספציפיים ממערך או מ-ArrayList, תוכל להשתמש במגוון של שיטות. דומה לאובייקטים אחרים ב-PowerShell, תוכל לגשת לכל האיברים של מערך על ידי פשוט לקרוא לאובייקט.

PS51> $BasicArray
John
Susie
Jim
Johnny
Carrie

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

PS51> $BasicArray[0]
John

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

PS51> $BasicArray[-1]
Carrie

אופרטור הטווח שלמדת עליו למעלה יכול גם לשמש כדי לאחזר אובייקטים של מערך על ידי מעקב אחרי אותה השיטה של קריאת האיברים. נניח שברצונך לאחזר את ארבעת השמות הראשונים במערך $BasicArray.

ניתן לראות למטה שאפשר לציין טווח של אינדקסים 0-3 שיחזיר את ארבעת האיברים הראשונים.

PS51> $BasicArray[0..3]
John
Susie
Jim
Johnny

מיטב השימושים עם מערכים בפוורשל

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

בדרך כלל, אם יש לך אוסף קטן של אובייקטים סביר להניח שלא תפסיק להבחין בין איך אתה מנהל את המערכים שלך. אך, אם יש לך אוסף גדול של אובייקטים חשוב להבין את ההבדלים כדי להשיג תוצאות אופטימליות.

בואו נחיל את מה שלמדתם עכשיו במקטע הקודם אודות ההבדל בין += ושימוש בשיטת Add() עם לולאה של 50,000 פריטים.

ראשית, צרו מערך ריק וְArrayList ריק כפי שמוצג למטה.

PS51> $MyArray = @()
PS51> $MyArrayList = [System.Collections.ArrayList]@()

לְאַחַר מִכֵּן, מלאו 50,000 אלמנטים בכל אוסף באמצעות אופרטור הטווח ולולאת foreach כפי שמוצג למטה.

@(0..50000).foreach({$MyArray += $_})
@(0..50000).foreach({$MyArrayList.Add($_)})

לבסוף, עטפו את הפקודות שלכם בביטוי והעבירו את הביטוי הזה לְ Measure-Command cmdlet. על ידי ביצוע הביטוי עם Measure-Command, תוכל לראות כמה זמן כל תהליך למעשה נוטל לבצע.

יש לזכור שכמו שלמדתם קודם, += יוצר מערך חדש במקום להוסיף למערך קיים.

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArray += $_})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 59
Milliseconds      : 58
Ticks             : 590585963
TotalDays         : 0.000683548568287037
TotalHours        : 0.0164051656388889
TotalMinutes      : 0.984309938333333
TotalSeconds      : 59.0585963
TotalMilliseconds : 59058.5963

PS51> Measure-Command -Expression {@(0..50000).foreach({$MyArrayList.Add($_)})}
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 139
Ticks             : 1399989
TotalDays         : 1.62035763888889E-06
TotalHours        : 3.88885833333333E-05
TotalMinutes      : 0.002333315
TotalSeconds      : 0.1399989
TotalMilliseconds : 139.9989

התוצאה? כמעט 60 שניות לעומת 139 מילישניות!

כפי שניתן לראות, זה הרבה יותר מהיר להשתמש ב־ArrayList עבור אוספים גדולים במקום להשתמש במערך בגודל קבוע.

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

אם יש לך סקריפט קיים שיוכל להיהנות משימוש ב־ArrayList במקום מערך, זה יהיה הזדמנות נהדרת לביצוע שדרוג מיידי!

קריאה נוספת

רוצה עוד טיפים כאלה? בדוק את הבלוג האישי שלי ב-PowerShell ב: https://nkasco.com/FriendsOfATA.

Source:
https://adamtheautomator.com/powershell-array/