105. Concat and Union extension methods

לפעמים יש לנו שני אוספים, ואנחנו רוצים לבצע פעולה על כל האיברים שלהם.

לשם כך אפשר להשתמש בExtension Method שנקראת Concat:

היא מקבלת שני IEnumerableים ומחזירה IEnumerable חדש שהוא השרשור שלהם, כלומר מכיל את כל האיברים של הראשון, ואז את כל האיברים של השני

דוגמת קוד:

במקום לכתוב משהו כזה:

1
2
3
4
5
6
7
8
9
foreach (Person child in cohenChildren)
{
// Do something
}
foreach (Person child in leviChildren)
{
// Do something (copy code and do the same)
}

נוכל לכתוב כך:

1
2
3
4
5
6
7
IEnumerable<Person> children =
cohenChildren.Concat(leviChildren);
foreach (Person child in children)
{
// Do something
}

ניתן כמובן לנחש איך זה ממומש.

קיים בלבול נפוץ בין Concat לUnion – הרבה פעמים משתמשים בUnion כאשר בעצם מתכוונים להשתמש בConcat.

Union עושה משהו דומה, אבל שונה – Union מבצע איחוד של האוספים כקבוצות מתמטיות – כלומר יוצר לנו IEnumerable חדש שיש בו את כל האיברים שנמצאים בקבוצה הראשונה או בקבוצה השנייה (ה"או" הוא או מתמטי) – אבל בגלל שמדובר בקבוצה, אף איבר לא יופיע בו יותר מפעם אחת, למשל:

1
2
3
4
5
IEnumerable<int> theNumbers =
new[] {4, 8, 15, 16, 23, 42};
IEnumerable<int> evenNumbers =
new[] {2, 4, 6, 8, 10};

אם נשתמש בConcat נקבל:

1
2
3
4
5
6
7
8
IEnumerable<int> numbers =
theNumbers.Concat(evenNumbers);
foreach (int number in numbers)
{
Console.WriteLine(number);
}
// 4 8 15 16 23 42 2 4 6 8 10

אם נשתמש לעומת זאת בUnion נקבל:

1
2
3
4
5
6
7
8
IEnumerable<int> numbers =
theNumbers.Union(evenNumbers);
foreach (int number in numbers)
{
Console.WriteLine(number);
}
// 4 8 15 16 23 42 2 6 10

איך Union משווה ששני איברים זהים? עם Equals, כמובן.


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

1
2
IEnumerable<Person> allChildren =
children.Concat(new[] { anotherChild });

מה שחשוב לציין על כל הExtension Methods האלה, זה שהן משתמשות בyield return, ולכן הן כולן Lazy, כלומר כאשר נשתמש עליהן על IEnumerableים, החישוב לא יתבצע עד שנריץ את הMoveNext.

הן לא הורסות לנו את הLaziness שמספקות לנו המתודות הבסיסיות של LINQ (Select, Where, SelectMany וכו’)

שתף