103. TakeWhile extension method

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

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

הדרך הקלאסית:

1
2
3
4
5
6
7
8
foreach (LogInfo logInfo in log)
{
if (logInfo.Error)
{
break;
}
// Analyze log info...
}

גם כאן LINQ מספקת לנו Extension Method שחוסך את העבודה הזאת, שמו TakeWhile.

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

דוגמה לשימוש:

1
2
IEnumerable<LogInfo> beforeError =
log.TakeWhile(info => !info.Error);

ואז נוכל לכתוב בכיף את הקוד הבא:

1
2
3
4
foreach (var logInfo in beforeError)
{
// Analyze log info...
}

למה זה טוב?

ראשית זה מאפשר לנו לבצע פעולות כאלה בצורה הצהרתית, בדומה לשאר הדברים בLINQ.

שנית, קוד בלי הkeywordים break, continue וgoto הוא קוד בריא יותר, ולכן עדיף 😃

כמו רוב הדברים שכבר ראינו, גם פה יש overload שמקבל גם index בשביל שנוכל להכניס אותו לשיקול בתנאי, למשל:

1
2
3
IEnumerable<LogInfo> beforeError =
log.TakeWhile((info, index) =>
(!info.Error) && (index <= 1000));

מוצא את אלף האיברים הראשונים לפני השגיאה.

יותר מזאת, אם מעניין אותנו לעשות רק תנאים על האינדקס, למשל להשיג רק את 1000 התוצאות הראשונות, נוכל להשתמש בExtension Method ששמו Take, שעושה את זה, במקום להעביר כל פעם delegate שעושה רק את התנאי הזה על האינדקס.

שתף