התנהגות מוזרה של מתודת ג'אווהסקריפט 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 של שני תתי המערכים האחרים. איזו עקביות יש כאן?!
-
יש לי מערך כעין זה.
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עבורitem1myArr.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
- הפונקציה של
-
רקע לתשובת @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
את הדוגמאות שם ראיתי, אבל הן לא עזרו לי כיוון שהן עוסקות במערך שכולו פרימטיבים ולא מערכים.
- הפונקציה של