פונקצית 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.

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

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

אהבתם? לא אהבתם? דרגו!


תגיות: פורסם בקטגוריה: פיתוח ב-JavaScript

אל תשארו מאחור! יש עוד מה ללמוד!

6 comments on “פונקצית reducer
  1. משה הגיב:

    היי רן תודה על המאמר
    תוכל להסביר מה זה בעצם שונה מהמתודה map?

  2. אדם הגיב:

    אחל׳ה מאמר. תיקון קטן – אם לא מעבירים פרמטר שלישי (ה initialValue), אז lastResult מתחיל מהאיבר הראשון במערך, לא מכלום (ואז יש איטרציה אחת פחות בעצם).

  3. מיכה הגיב:

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

כתיבת תגובה

האימייל לא יוצג באתר.

רישום