התנהגות מוזרה של מתודת ג'אווהסקריפט reduce
-
יש לי מערך כעין זה.
let myArr = [[1, 33], ["abc", 50], [12, 90]];
כל אייטם במערך הוא מערך בן שני אייטמים, שהשני ביניהם (אינדקס 1) הוא מספר.
לשם הוצאת הסכום של כל הרכיבים השניים בתתי-המערכים, רציתי להשתמש במתודת reduce של JS – שתפקידה לעבור על מערך ולהוציא ערך יחיד לפי פונקציית callback; וכה כתבתי:
myArr.reduce((item, item2) => item1[1] + item2[1]);
זה נראה שימוש נכון במתודה. אבל נעלבתי מאוד לקבל תשובה שגויה: "NaN"!
למה NaN?!
לתוספת הילת התעלומה, כשכתבתי לאמר:
myArr.reduce((item1,item2) => item1 + item2[1]);
התשובה הייתה:
'1,335090'
כלומר סטרינג של תת-המערך הראשון בשלמותו, עם אייטמי 1 של שני תתי המערכים האחרים. איזו עקביות יש כאן?!
-
@שלום-עולם-0 אתה צריך לעקוב אחרי התוכן של ה-
accumulator
(=item1
)במקרה הראשון: באיטרציה הראשונה הוא מערך שערכו:
[1, 33]
, אבל באיטרציה השניה זה המספר:83
כי זה מה שהחזרת מהאיטרציה הראשונה, עכשיו הערך שלitem1[1]
זהundefined
וחיבור שלו עם90
מניבNaN
במקרה השני: באיטרציה הראשונהitem1
הוא מערך, התוצאה של חיבור מערך עם מספר הוא המרת המערך למחרוזת (welcome to JS...), וההמשך מובן...הפתרון הוא להוסיף ערך ראשוני של
0
עבורitem1
myArr.reduce((item1,item2) => item1 + item2[1], 0);
-
רקע לתשובת @yossiz:
- הפונקציה של
reduce
לא מקבלת ארגומנט שלitem1
ו-item2
דהיינו האיבר הנוכחי במערך והאיבר הקודם, אלאaccumulator
(כלומר ההצטברות עד עכשיו, ראה בהמשך), וcurrentItem
כלומר האיבר הנוכחי. - אם לא מעבירים ערך ראשוני (
initialValue
), הערך ההתחלתי (כלומר הaccumulator
- ההצטברות, באיטרציה הראשונה) יהיה הערך הראשון של המערך.
אתה יכול לראות כאן מבנה של פונקציית reduce תקינה: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#try_it
- הפונקציה של
-
@צדיק-תמים כתב בהתנהגות מוזרה של מתודת ג'אווהסקריפט reduce:
אתה יכול לראות כאן מבנה של פונקציית reduce תקינה: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#try_it
את הדוגמאות שם ראיתי, אבל הן לא עזרו לי כיוון שהן עוסקות במערך שכולו פרימטיבים ולא מערכים.