חוקי הפורום

JavaScript Iterator עם כל המתודות השימושיות של מערך



  • למערך יש שפע של מתודות שימושיות: fliter, some, find, reduce ועוד.
    בIterators אין כל אלה (לא הבנתי למה עוד לא עשו).
    הדרך הרגילה היא לעשות [...] או Array.from אבל זה הפסד משמעותי של ביצועים בהתאם לסוג הגנרטור.
    ראיתי בSO קוד כה קצר ופשוט שמפעיל את המתודות גם בIterator:

    var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
    IteratorPrototype.map = function*(f) {
        for (var x of this)
            yield f(x);
    };
    IteratorPrototype.filter = function*(p) {
        for (var x of this)
            if (p(x))
                yield x;
    };
    IteratorPrototype.scan = function*(f, acc) {
        for (var x of this)
            yield acc = f(acc, x);
        return acc;
    };
    IteratorPrototype.reduce = function(f, acc) {
        for (var x of this)
            acc = f(acc, x);
        return acc;
    };
    
    

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



  • @dovid אני לא מבין איך משתמשים בזה 😞
    ככה??

    for (node of document.querySelectorAll('*')[Symbol.iterator]().filter(node => node.nodeName === 'DIV')) console.log(node)
    

    יש דרך יותר אלגנטי?



  • @yossiz אתה צודק לגמרי... אני נשמרתי מהאפשרות שאני טועה (חשבתי שNodeList הוא iterable), ולכן לא הזכרתי בחצי מילה את המקרה שהביא אותי לכתוב את הפוסט.
    זה הפריע לי בעבר בדברים הרבה יותר משמעותיים, ולכן מצאתי בקעה להתגדר בה.
    עכ"פ אתה עצמך הבאת קוד שלא הייתי יודע לכתוב ואני לא מבין אותו:

    document.querySelectorAll('*')[Symbol.iterator]
    

    מה זה? ואם זה עובד טוב (מבחינת הפעילות מאחורי הקלעים, שלא נעשה מעבר כפול והעתקה) מה לא אלגנטי פה, האריכות?


  • תכנות

    @dovid
    אשמח לדוגמאות שימוש.



  • @dovid אמר בJavaScript Iterator עם כל המתודות השימושיות של מערך:

    האפשרות שאני טועה (חשבתי שNodeList הוא iterable)

    אני מסופק אם אתה מתכוון להכריע שזה כן iterator או לא או שאתה מסופק... בכל מקרה זה כן iterator.

    עכ"פ אתה עצמך הבאת קוד שלא הייתי יודע לכתוב ואני לא מבין אותו:
    document.querySelectorAll('*')[Symbol.iterator]

    מה זה?

    מכיון ש-NodeList הוא iterable לכן יש לו מאפיין [Symbol.iterator] שהיא פונקציה שמחזירה iterator. אני לוקח את ה-iterator וקורא עליו filter שמחזירה iterator מפולטר.

    ואם זה עובד טוב (מבחינת הפעילות מאחורי הקלעים, שלא נעשה מעבר כפול והעתקה) מה לא אלגנטי פה, האריכות?

    זה עובד טוב (לכאורה) כלומר שאין מעבר כפול והעתקה. אבל אפשר לקבל אותו דבר עם קוד קריא:

    for (node of document.querySelectorAll('*')) {
      if (node.nodeName === 'DIV') console.log(node);
    }
    

    מה שחסר יותר זה דרך לקרוא filter ישר על NodeList וזה אתה לא מספק לנו לכאורה.



  • @yossiz אתמול ניסיתי לעשות בזריזות for...of וקיבלתי שגיאה שזה לא iterable והתפלאתי מאוד, ולכן הגעתי למסקנה שזה לא. אני סקרן מה הייתה טעותי, כנראה טעות כתיב.
    כעת הבנתי הכל למפרע. אתה די צודק והקוד זה לא מספיק מיקל, כי הוא נרחיב רק את האיטרטור ולא את האובייקט שמחזיק אותו (האיטיירבל).
    אני כן הייתי מעדיף את הפתרון אותו חשבתי שיש, בהתחשב במספר פעמים רב של שימוש, ובהצטרף מתודות יחד כמו פילטר ושוב פילטר ואז reduce ואז some, קוד מוכן כזה עושה קלות תחזוקה וחיסכון בשגיאות. ולזה אני חושב שהקוד שהבאת הוא חצי פתרון ואני לא רואה בו סרבול רב.




  • תכנות

    @dovid אמר בJavaScript Iterator עם כל המתודות השימושיות של מערך:

    למערך יש שפע של מתודות שימושיות: fliter, some, find, reduce ועוד.
    בIterators אין כל אלה (לא הבנתי למה עוד לא עשו).

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


התחבר כדי לפרסם תגובה