130. Zip extension method

הכרנו בעבר את הפונקציה Select היוצרת אוסף חדש של אובייקטים ע”י “הטלה” כלשהי על האובייקטים הקיימים:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IEnumerable<Person> people =
new []
{
new Person("John", "Lennon"),
new Person("Ringo", "Starr"),
new Person("Paul", "McCartney"),
new Person("George", "Harrison")
};
IEnumerable<string> firstNames =
people.Select(x => x.FirstName);
// John, Ringo, Paul, George
IEnumerable<string> lastNames =
people.Select(x => x.LastName);
// Lennon, Starr, McCartney, Harrison

לפעמים יש לנו את המצב ההפוך: נתונות לנו ההטלות (במקרה שלנו השמות הפרטיים והמשפחה), ואנחנו מעוניינים לבנות אובייקט על פיהן.

כלומר יש לנו רק את firstNames ואת lastNames ולפי זה אנחנו מעוניינים ליצור את people.

(תחשבו שמצב כזה יכול לקרות כאשר אנחנו קוראים את firstNames ואת lastNames ממקור חיצוני, למשל מקובץ או שליפה מDB)

לפי Framework 4.0 היינו צריכים לעשות משהו כזה:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<Person> people = new List<Person>();
using (IEnumerator<string> firstNamesIterator =
firstNames.GetEnumerator())
{
using (IEnumerator<string> lastNamesIterator =
lastNames.GetEnumerator())
{
while (firstNamesIterator.MoveNext() &&
lastNamesIterator.MoveNext())
{
people.Add
(new Person(firstNamesIterator.Current,
lastNamesIterator.Current));
}
}
}

עובד, אבל לא אלגנטי! (מישהו באמת משתמש בGetEnumerator????)

החל מFramework 4.0 נוכל לעשות זאת באופן יותר פשוט באמצעות הExtension Method שנוסף לSystem.Linq שנקרא Zip:

1
2
3
IEnumerable<Person> people =
firstNames.Zip(lastNames,
(first, last) => new Person(first, last));

הExtension Method מקבל עוד IEnumerable ומאפשר לנו ליצור מכל זוג של איברים (לפי המיקום שלהם), איבר שלישי באמצעות delegate שאנחנו מציינים.

כלומר הוא רץ סימולטנית על שני האוספים שלנו, ומביא לנו בכל איטרציה את האיבר הנוכחי של כל אוסף, ובאמצעות הDelegate מאפשר לנו ליצור איבר חדש. מהאיברים החדשים שנוצרו, מורכב הEnumerable החדש.

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

סופ"ש טוב (בלי הרבה זיפזופים)

שתף