פונקצית reducer

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

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

בואו ונתחיל בהגדרה היבשה, ממש זו שב-MDN, מתודת reducer, שנמצאת במערך בלבד, מאפשרת לנו להעביר פונקציה עם ארבעה ארגומנטים:

  1. הערך שהתקבל מההרצה של פונקצית ה-reduce על האיבר הקודם (אם יש כזה).
  2. האיבר הנוכחי.
  3. האינדקס.
  4. המערך שה-reduce עליו.

הפונקציה עוברת על כל איבר במערך. אנחנו יכולים להחזיר ערך שיעבור לארגומנט שיועבר לפונקציה הבאה בתור (זו שתרוץ על האיבר הבא).

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

function reducerFunction(lastResult, currentValue) {
  return lastResult + currentValue;
}

const myArray = ['avi', 'itzhak', 'yaki'];

const reducedValue = myArray.reduce(reducerFunction);

console.log(reducedValue); // aviitzhakyaki 

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

בהרצה הראשונה, אין את lastResult, אז ה-reducer מחזיר את הערך הנוכחי (והראשון) של המערך. avi.

בהרצה השניה, ה-lastResult הוא avi. אז ה-reducer מחברת אותו אל הערך של האיבר הנוכחי (והשני) של המערך. itzhak ומחזירה aviitzhak.

בהרצה השלישית, ה-lastresult הוא aviitzhak, זה מה שההרצה הקודמת החזירה. ה-reducer לוקחת אותו ומחברת אותו אל הערך של האיבר הנוכחי (והשלישי) של המערך ומחזירה aviitzhakyaki.

מה שההרצה האחרונה מחזירה, זה מה שה-reducer מחזירה.

See the Pen reducer by Ran Bar-Zik (@barzik-the-vuer) on CodePen.

אנו יכולים לקבוע את הערך של ה-lastResult אפילו אם מדובר בהרצה הראשונה, אם אנו מעבירים ארגומנט נוסף. הנה פיתוח של הדוגמה הקודמת. הפעם אני מעביר ארגומנט שני בפונקצית ה-reduce:

function reducerFunction(lastResult, currentValue) {
  return `${lastResult}  ${currentValue}`;
}

const myArray = ['avi', 'itzhak', 'yaki'];

const reducedValue = myArray.reduce(reducerFunction, 'Names:');

console.log(reducedValue); // Names:  avi  itzhak  yaki

מה מתרחש כאן?

בהרצה הראשונה, לכאורה אין את lastResult, אבל השתמשנו בארגומנט השני כשקראנו ל-myArray.reduce/ אז ה-reducer לוקח את הערך הזה, מכניס אותו למחרוזת טקסט יחד עם הערך של האיבר הראשון (avi) ומחזיר את התוצאה: Names: avi.

בהרצה השניה, ה-lastResult הוא Names: avi. אז ה-reducer לוקחת את הערך הזה ומכניסה אותו למחרוזת טקסט עם הערך של האיבר השני (itzhak) וכך הלאה.

ברגע שמבינים את ה-reducer, מבינים כמה כוח יש לה. אני יכול לעשות המרות של מערכים בקלות לכל דבר. למשל, נניח שאני מקבל מערך של נתונים מצד השרת שנראה כך:

function reducerFunction(accumulator, currentValue) {
  accumulator[currentValue.name] = currentValue; 
  return accumulator;
}

const mySites = [{ name: 'Google', url: 'google.com' },
                { name: 'Internet Israel', url: 'internet-israel.com' },
                { name: 'Haaretz', url: 'haaretz.co.il' },
                { name: 'GOV IL', url: 'gov.il' },];

const reducedValue = mySites.reduce(reducerFunction, {});

console.log(reducedValue); 

וכך אני יכול להמיר את המערך לאובייקט. שימו לב שאני קובע שהאובייקט הראשוני יהיה אובייקט ריק באמצעות העברתו כארגומנט שני כאשר אנו מבצע פעולת reduce על מערך.

See the Pen reducer advanced by Ran Bar-Zik (@barzik-the-vuer) on CodePen.

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

פוסטים נוספים שכדאי לקרוא

גלילה לראש העמוד