
הטקסט המלא של הדקות הראשונות בהרצאה «אוספים - Collections - חלק 1» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אנחנו מתחילים עם נושא מאוד בסיסי ומאוד חשוב וגם מאוד מאוד נפוץ שנקרא Collections, אוספים. אוסף או קולקשן זה בעצם איזושהי מחלקה שניתן להכניס לתוכה מספר רב של פריטים, כאשר יש בין כל הפריטים האלה בדרך כלל איזשהו משהו משותף.
לדוגמה, אם אנחנו רוצים באיזשהו פרויקט להחזיק הרבה הרבה מוצרים במחלקה אחת, אם אנחנו רוצים הרבה לקוחות או ספקים או עובדים או כל פעם שאנחנו רוצים להחזיק הרבה פריטים ולנהל את אוסף הפריטים הזה אז אנחנו צריכים להתעסק עם משהו שנקרא קולקשן.
אז קודם כל אנחנו מכירים מעולם האלגוריתמיקה כל מיני סוגים של קולקשנים בסיסיים שאנחנו קודם כל הולכים לראות אותם כאן ונבין איזשהו חיסרון או איזושהי אי יכולת מסוימת שקיימת עבור הקולקשנים האלה.
ואני מדבר על מערכים רגילים. בואו ניקח פרויקט, נקרא לו ארייז, ומה שאנחנו הולכים לראות זה בעצם כל מיני מערכים סטנדרטיים שאתם בטח נחשפתם אליהם. הדבר הראשון שאנחנו הולכים לראות זה מערך חד-ממדי רגיל.
בואו נניח שאנחנו רוצים סדרה של מספרים. אז אנחנו יודעים מהמודול של האלגוריתמיקה שאנחנו יכולים לפתוח לדוגמה דבר כזה עם סוגריים מרובעים, נקרא לזה הרי פשוט ובוא נניח שאנחנו רוצים שהמערך הזה יהיה מסוג של אינט כמובן בגודל 10. איך היינו יכולים לרוץ על המערך ולהכניס אליו ערכים?
יש לנו יכולת לרוץ בלולאה רגילה, יש לנו אפשרות להגיע ללנקס של המערך, יש לנו אפשרות להגיע לפריט בודד במערך ולהכניס לתוכו איזשהו מספר.
נכניס לתוכו את i כפול i. אנחנו יכולים גם בעזרת for each לרוץ על המערך הזה ואנחנו יכולים בעזרת for each להציג את כל אחד מהפריטים שקיימים בתוך המערך בצורה כזאת.
בואו נריץ ואנחנו רואים שהכל מוצג לנו על המסך והכל בסדר. אז קודם כל אם אנחנו רוצים סדרה של פריטים כמובן שאנחנו יכולים לקחת את הקונספט של מערך חד-ממדי ובתוך המערך החד-ממדי הזה אם אני רושם הרי נקודה, כמובן שיש לנו פה המון פונקציות שמאפשרות לנו לעשות כל מיני דברים, לחפש כל מיני דברים,
לבצע כל מיני פעולות שונות על המערך עצמו. חלק מהפונקציות האלה אנחנו נראה בהמשך הסרטון. אפשרות אחרת זה שיש לנו יכולת ליצור משהו שנקרא מטריצה.
בואו ניקח את כל הקבוצה הזאת של שורות הקוד ונוציא אותה לפונקציה חיצונית, נקרא לה פונקציה test array. נשים את זה בהערה ונסתכל על מטריצה.
אם הייתי רוצה מטריצה של מספרים זאת השיטה לפתוח מטריצה שזה בעצם איזושהי טבלה שיש לה שורות ועמודות. בואו נפתח בגודל בוא נניח של 10 שורות על 20 עמודות.
תמיד המספר הראשון זה מספר השורות והמספר השני זה מספר העמודות. כעת אנחנו רוצים לרוץ ולהכניס למטריצה בוא נניח ערכים רנדומליים. נניח שיש לנו פה איזשהו רנדום rnd שווה ו-new random, נרוץ בלולאה אחת על השורות של המטריצה, זה יהיה matrix.getLength 0, 0 זה מספר השורות שאנחנו רוצים,
עוד לולאה שהפעם תרוץ על j.matrix.getLength של 1, זה יהיה מספר העמודות, יש לנו פה 10 שורות ויש לנו פה 20 עמודות, וכעת אנחנו יכולים לפנות למטריצה, במיקום i.thick.j ולהכניס איזשהו מספר רנדומלי rnd.next בואו נניח בין 1 ל-100 זה יהיה בין 1 ל-100 ובואו נניח שניקח עוד מטריצה או יותר נכון לולה מקוננת נוספת והפעם נציג את
הפרטים נרשום console.writeline נציג את הפריט במטריצה בואו נציג אותו אפילו בצורה כזאת ואז אנחנו יכולים להגדיר שהפריט במיקום 0, נפתח לו בוא נניח איזה 4 או 3 תאים ונרד שורה פה.
בואו נסתכל על ההדפסה עצמה ויש לנו את המטריצה מוצגת לנו על המסך בצורה של טבלה. אז אנחנו יודעים מעולם האלגוריתמיקה שיש לנו גם יכולת לפתוח מטריצה.
בואו נוציא את כל הדברים האלה לפונקציה חיצונית, תכף אנחנו נדבר מתי להשתמש במה, נקרא לפונקציה test.matrix. ואפשרות נוספת שקיימת לנו גם היא מעולם האלגוריתמיקה זה להשתמש במשהו שנקרא jagged array, מערך משונן.
מערך משונן זה בעצם מערך של מערכים. זה לא מערך חד-ממדי וזה לא מטריצה. מה זה אומר? פותחים אותו בצורה כזאת ויש לנו מערך חד-ממדי שכל טאבו זה מערך בפני עצמו.
בואו נקרא לזה jagged שווה new int. אנחנו מגדירים שהמערך הראשון בואו נניח הוא מגודל 5 והוא מערך של מערכים. כעת מה שאנחנו צריכים לעשות זה לרוץ על המערך jagged array lengths ואנחנו רוצים לפנות לכל אחד מהתאים במערך ולהכניס לכל תא מערך אמיתי אחר.
בואו נגיד אפילו שכל אחד מהתאים של המערכים או יותר נכון כל אחד מהמערכים עצמם הוא בגודל אחר. בואו ניקח אפילו כאן איזשהו אובייקט לייצור מספרים רנדומליים, ונגיד שאנחנו רוצים מערך שהאורך שלו זה בין 10 לבין 20 ערכים, וכעת אנחנו רוצים לרוץ על המערך שכרגע יצרנו,
jagged על i.length, ולהכניס לכל אחד מהערכים שלו איזשהו מספר כלשהו. אז אנחנו פה ב-i במיקום j, נייצר איזשהו מספר שהופען בין 1 ל-100 בצורה כזאת.
לולה נוספת עבור הדפסה, בואו ניקח אפילו את הקונספט של הלולה הזאת, נדפיס את זה פה, ורק נדפיס jugged ij בצורה כזאת עם ירידת תשואה.
בואו נבדוק את זה, ונראה שיש לנו סדרה של מערכים שכל מערך יכול להיות בגודל שונה, כי יש לנו בעצם מערך אחד בגודל 5 שכל טאבו זה מערך שכמובן יכול להיות בגודל אחר וכל מה שראינו כרגע זה בעצם בא מעולם האלגוריתמיקה אפשר להגיד שהוא גם קשור לאובג'קט אוריינטד כמובן ואלה נקראים אוספים פשוטים שקיימים בילד
אין כחלק משפת התכנות c-sharp בואו נוציא גם את זה לפונקציה והדבר הראשון שאני רוצה לדבר עליו זה מתי להשתמש בכל אחד מהכלים שכרגע ראינו. למה זה טוב לנו לדעת אותם?
מתי להשתמש בכל אחד מהם? אז קודם כל הדבר הנפוץ ביותר שמשתמשים איתו זה כמובן מערך חד-ממדי. מערך חד-ממדי, כל פעם שאתם רוצים שיהיה לכם סדרה של ערכים חד-ממדיים, קבוצה של פריטים בלבד, אז אנחנו יכולים לפתוח מערך חד-ממדי בשביל לטפל בהם.
כאשר אנחנו רוצים משהו שנראה כמו טבלה, מידע טבלאי. לדוגמה, אנחנו רוצים ציונים של שכבה שלמה של בית ספר. אז אם אנחנו רוצים ציונים של כיתה אחת, בוא נניח של מבחן מסוים בכיתה אחת, אז כמובן מערך חד-ממדי מספיק לנו.
אבל אם אנחנו רוצים של שכבה שלמה, אז אולי אנחנו רוצים סדרת מערכים, ואז אנחנו יכולים לסדר את זה בצורה של מטריצה. בדרך כלל השימוש של מטריצה זה עבור משחקים שכוללים לוחות כמו לוח שח, לוח דמקה, לוח ששבש, לוח של איקסי גול, כל מיני דברים שדורשים שאותם שורות יהיו לי בכל אחת מהעמודות,
או ליתר דיוק אותם עמודות, אותו מספר עמודות בכל אחת מהשורות. זה בעסיקלי מטריצה. אז אולי הדוגמה של ציונים עבור שכבה שלמה זה לא הדוגמה הכי נכונה כי לא בטוח שבכל כיתה יש לי אותו מספר תלמידים.
במידה ואנחנו רוצים שבכל כיתה יכול להיות לנו מספר תלמידים שונה ולכן מספר ציונים שונה, ג'אגד הרי יהיה יותר מתאים לנו. ואז אנחנו יכולים להגדיר מערך של מערכים שכל מערך מתאר ציונים של כיתה אחת והם כמובן יכולים להיות באורך שונה כל אחד.
ובייסיקלי שלושת הדברים האלה זה דברים שכבר היינו אמורים לדעת מסרטונים קודמים. שלושת הכלים האלה קשורים לעולם האוספים אבל ישנו איזשהו חיסרון מסוים או אי יכולת מסוימת בכל שלושת הכלים האלה שכרגע ראינו והחיסרון הגדול ביותר שקיים בהם זה שמהרגע שהגדרתם את הישות שלכם בוא ניקח אפילו את המטריצה או את המערך החד מימדי שאנחנו ראינו פה מהרגע שהגדרנו אותו אנחנו לא יכולים לשנות
את גודלו וזה חיסרון שיכול להיות לא מתאים לנו פשוט. ברגע שהגדרתי את המערך הזה בגודל 10, המערך הזה הוא תמיד בגודל 10. אנחנו לא יכולים ללכת ולהוסיף לו פריט חדש.
אין למערך שום פונקציה add או insert להוספה של פריט. אין למערך שום פונקציה של remove או delete בשביל הסרה של פריט. כנ"ל n למטריצה, כנ"ל n לג'אגדה ריי, כי בעצם ג'אג דארי זה מערך של מערכים, אז אם למערך חד-ממדי אין את היכולת הזאת, ברור שלג'אג דארי לא יהיה אותה.
וזה אומר שברוב המקרים, פתאום אנחנו רואים, או בהרבה מקרים אנחנו רואים, שזה פשוט לא יתאים לנו. כי בוא נניח שאנחנו רוצים אוסף שמחזיק לנו מוצרים שיש לנו בחנות, שאנחנו צריכים לבנות תוכנה עבורה.
יכול להיות לנו אלף מוצרים, יכול להיות לנו עשרת אלפים מוצרים, אבל אנחנו לא בדיוק יודעים כמה מוצרים הולכים להתווסף עם הזמן.
אז אם היינו משתמשים במערך חד-ממדי זה אומר שאנחנו צריכים עכשיו לפתוח אותו מספיק גדול בכדי להחזיק כל מוצר עתידי שיכולים להוסיף בהמשך. וזה יכול להיות בזבוז כי מה הגודל שנפתח אותו? מיליון תאים?
אז אם לא נגיע אפילו לאלף מוצרים סתם בזבזנו מיליון תאים בזיכרון ואם הגדרנו 100,000 תאים וביום בהיר אחד פתאום מגיע 100,001 מוצרים, אז פתאום יש לנו פה איזושהי בעיה.
ולכן שימוש כזה במערך חד-ממדי או במטריצה או בג'אגדה ריי הוא לא מתאים כאשר אנחנו רוצים שתהיה לנו את היכולת להוסיף פריטים לאוסף ולמחוק פריטים מהאוסף. אם היינו הולכים ורושמים דבר כזה, שווה לניו אינט בגודל 20 במקום 10 במהלך התוכנית, כמובן שהיינו דורסים את המערך הקודם ומאבדים את כל הערכים שבו.
אם היינו עושים דבר כזה, היינו צריכים לבצע העתקה של כל המידע הקודם למערך החדש, ואז היינו יכולים להמשיך לעבוד עם המערך החדש אחרי שהגדלנו אותו.