פצל רשימה לחלקים בקוטלין

1. הקדמה

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

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

2. פיצול רשימה לרשימת זוגות

לדוגמאות שלנו נשתמש בשתי רשימות - אחת עם מספר זוגי של אלמנטים ואחת עם מספר אי זוגי של אלמנטים:

val evenList = listOf (0, "a", 1, "b", 2, "c"); val unevenList = listOf (0, "a", 1, "b", 2, "c", 3);

ברור שאנחנו יכולים לחלק את זה שלנו evenList לשלושה זוגות בדיוק. עם זאת, שלנו unevenList יהיה אלמנט נוסף נוסף.

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

2.1. באמצעות groupBy

ראשית, בוא ניישם פתרון עם groupBy. ניצור רשימה עם מספרים עולים ושימוש groupBy לפצל אותם:

val numberList = listOf (1, 2, 3, 4, 5, 6); numberList.groupBy {(it + 1) / 2} .values

זה נותן את התוצאה הרצויה:

[[1, 2], [3, 4], [5, 6]]

איך זה עובד? נו, groupBy מבצעת את הפונקציה שסופקה (זה +1) / 2 על כל אלמנט:

  • (1 + 1) / 2 = 1
  • (2 + 1) / 2 = 1.5, המעוגל ל -1
  • (3 + 1) / 2 = 2
  • (4 + 1) / 2 = 2.5, המעוגל ל -2
  • (5 + 1) / 2 = 3
  • (6 + 1) / 2 = 3.5, המעוגל ל -3

לאחר מכן, groupBy מקבץ את האלמנטים ברשימה שנתנו את אותה התוצאה.

עכשיו, כשאנחנו עושים את אותו הדבר עם רשימה לא אחידה:

val numberList = listOf (1, 2, 3, 4, 5, 6, 7); numberList.groupBy {(it + 1) / 2} .values

אנו מקבלים את כל הזוגות ואלמנט נוסף נוסף:

[[1, 2], [3, 4], [5, 6], [7]]

אבל, אם נלך רחוק יותר עם מספרים אקראיים:

val numberList = listOf (1, 3, 8, 20, 23, 30); numberList.groupBy {(it + 1) / 2}. ערכים

נקבל משהו שהוא לא רצוי לחלוטין:

[[1], [3], [8], [20], [23], [30]]

הסיבה היא פשוטה; החלת ה- (זה +1) / 2 פונקציה בכל אלמנט נותנת: 1, 2, 4, 10, 12, 15. כל התוצאות שונות, ולכן אין אלמנטים מקובצים יחד.

כשאנחנו משתמשים שלנו evenList אוֹ unevenListזה אפילו יותר גרוע - הקוד לא מתגודד, כיוון שלא ניתן להחיל את הפונקציה מיתרים.

2.2. באמצעות groupBy ו עם אינדקס

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

evenList.withIndex () .groupBy על ידי {it.index / 2}. מפה {it.value.map {it.value}}

זה מחזיר את רשימת הזוגות שאנחנו רוצים:

[[0, "a"], [1, "b"], [2, "c"]]

יתר על כן, אם אנו משתמשים ב- unevenList, אנחנו אפילו מקבלים את האלמנט הנפרד שלנו:

[[0, "a"], [1, "b"], [2, "c"], [3]]

2.3. באמצעות groupBy עם foldIndexed

אנחנו יכולים ללכת צעד רחוק יותר מאשר רק להשתמש אינדקס ולתכנת קצת יותר עם foldIndexed כדי לחסוך כמה הקצאות:

evenList.foldIndexed (ArrayList(evenList.size / 2)) {index, acc, item -> if (index% 2 == 0) {acc.add (ArrayList (2))} acc.last (). add (item) acc}

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

2.4. באמצעות נתח

אבל, אנחנו יכולים לעשות את זה בצורה אלגנטית יותר עם נתח. אז בואו נשתמש בשיטה על שלנו evenList:

evenList.chunked (2)

ה evenList מספק לנו את הזוגות שאנחנו רוצים:

[[0, "a"], [1, "b"], [2, "c"]]

בזמן ש unevenList נותן לנו את הזוגות ואת האלמנט הנוסף:

[[0, "a"], [1, "b"], [2, "c"], [3]]

2.5. באמצעות חלון

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

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

כברירת מחדל, partialWindows הוא שֶׁקֶר. לכן ההצהרות הבאות מניבות את אותה התוצאה:

evenList.windowed (2, 2) unevenList.windowed (2, 2, false)

שניהם מחזירים את הרשימה ללא האלמנט הנפרד:

[[0, "a"], [1, "b"], [2, "c"]]

לבסוף, כאשר קבענו partialWindows ל נָכוֹן לכלול את התוצאה החלקית:

unevenList.windowed (2, 2, נכון)

נקבל את רשימת הזוגות בתוספת האלמנט הנפרד:

[[0, "a"], [1, "b"], [2, "c"], [3]]

3. מסקנה

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

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

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

כרגיל, קוד המקור המלא זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found