דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. ארכיון code613m
  4. JS: uniq על מערך של אובייקטים

JS: uniq על מערך של אובייקטים

מתוזמן נעוץ נעול הועבר ארכיון code613m
18 פוסטים 4 כותבים 1.2k צפיות 4 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • A מנותק
    A מנותק
    avr416
    כתב ב נערך לאחרונה על ידי
    #6

    @דוד ל.ט.

    אגב תחשוב, מה היית עושה עם linq? גם שם זה לא פשוט. השוואה לפי כלל המאפיינים קיימת בהשוואת struct, אבל במחלקות אין ברירה חוץ מרפלקשיין. כמובן תמיד ניתן להכין באובייקט מתודת השוואה ו/או לדרוס את הGetHashCode או להשתמש בIComparer וכו'.
    אגב ראיתי כשמונה ספריות פופולריות של linq בjs ולבטח יש עוד הרבה...

    עוד לא יצא לי שהייתי צריך להשתמש בדבר כזה..

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

    לפי מה שכתבת אז אני חושב שהיה אפשר גם לכתוב ככה, כדי להשיג אח"כ גם את התוכן:

    var array = [{id:15, name: "עברית"},{id:15, name: "עברית"},{id:15, name: "עברית"},{id:16, name: "תורה"}]
    var uniq = array.map(x=>x.name).filter((v,i,arr) => arr.indexOf(v) ===i )   
    var uniqArr = uniq.map(x => array[array.findIndex(y => y.name === x.name)])
    
    console.log(uniq) 
    console.log(uniqArr)
    

    אבל משום מה זה לא עובד..
    כלומר הוא יוצר לי מערך ייחודי רק של הname. אולם, אח"כ הוא מחזיר לי כאילו השם הזה לא קיים במערך המקורי. -1
    אא"כ אני כותב לו את השם המפורש 🙂 דהיינו =='עברית' ואז אכן הוא מחזיר לי את האינדקס.. אלא שכמובן שאני לא יודע מה יהיה אותו תוכן..

    פורסם במקור בפורום CODE613 ב20/07/2017 10:26 (+03:00)

    תגובה 1 תגובה אחרונה
    0
    • dovidD מחובר
      dovidD מחובר
      dovid
      ניהול
      כתב ב נערך לאחרונה על ידי
      #7

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

      var array = [{id:15, name: "עברית"},{id:15, name: "עברית"},{id:15, name: "עברית"},{id:16, name: "תורה"}];
      var uniqArr = array.filter((item, index) => array.findIndex(x => x.name == item.name) == index);
                          
      console.log(uniqArr);
      

      ואם ע"י הmap, ובהנחה שדרוש רק השוואת מאפיין name, אז ככה:

      var array = [{id:15, name: "עברית"},{id:15, name: "עברית"},{id:15, name: "עברית"},{id:16, name: "תורה"}];
      var arrForIndexs = array.map(x => x.name);
      var uniqArr = array.filter((item, index) => arrForIndexs.indexOf(item.name) == index);
      console.log(uniqArr);
      

      פורסם במקור בפורום CODE613 ב20/07/2017 14:03 (+03:00)

      • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
      • בכל נושא אפשר ליצור קשר dovid@tchumim.com
      תגובה 1 תגובה אחרונה
      1
      • dovidD מחובר
        dovidD מחובר
        dovid
        ניהול
        כתב ב נערך לאחרונה על ידי
        #8

        אגב, מי שעושה כאלה מוניפולציות בקוד יותר מפעם אחת חייב חייב להשתמש בunderscore.
        לא בשביל חיסכון הזמן (כי בכל מקרה שורפים זמן איך לעשות בunserscore...) אלא בשביל נאמנות הקוד וקלות תחזוקו.
        אני יודע שנמאס להוסיף עוד ועוד תלויות אבל underscore נחוץ כל שתי שורות קוד שקשורים למערך.

        פורסם במקור בפורום CODE613 ב20/07/2017 14:21 (+03:00)

        • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
        • בכל נושא אפשר ליצור קשר dovid@tchumim.com
        תגובה 1 תגובה אחרונה
        1
        • רחמיםר מנותק
          רחמיםר מנותק
          רחמים
          מורחק
          כתב ב נערך לאחרונה על ידי
          #9

          תבדוק את זה:
          https://codepen.io/anon/pen/WOVRBg?editors=1112

          var array = [{id:15, name: "עברית"},
                       {id:15, name: "עברית"},
                       {id:15, name: "עברית"},
                       {id:16, name: "תורה"}]
          var uniq = {};
          array.forEach(function(i) {
              uniq[i.id] = i;
          });
          console.log(uniq);
          

          פורסם במקור בפורום CODE613 ב20/07/2017 16:13 (+03:00)

          תגובה 1 תגובה אחרונה
          1
          • dovidD מחובר
            dovidD מחובר
            dovid
            ניהול
            כתב ב נערך לאחרונה על ידי
            #10

            רחמים פתרון יפה, אבל אם כבר לפי איבר מסויים אז הבנתי שזה הname רק שצריך את המאפיין גם של הID. אז אם ככה uniq[i.name].
            וavr416 פעם הבאה חוץ מהבעיה תסביר מה המטרה הרצוייה, והם שייך מקרה של id שונה ושם זהה ומה הדין בכהאי גונא ומדוע 🙂

            פורסם במקור בפורום CODE613 ב20/07/2017 17:41 (+03:00)

            • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
            • בכל נושא אפשר ליצור קשר dovid@tchumim.com
            תגובה 1 תגובה אחרונה
            2
            • רחמיםר מנותק
              רחמיםר מנותק
              רחמים
              מורחק
              כתב ב נערך לאחרונה על ידי
              #11

              הפתרון שכתבתי לעיל עדיף משמעותית מבחינת מהירות [פי 20] על פני שימוש במערך רגיל.
              ראה ניסוי כאן
              http://jsben.ch/GYK6P

              פורסם במקור בפורום CODE613 ב20/07/2017 19:05 (+03:00)

              תגובה 1 תגובה אחרונה
              1
              • A מנותק
                A מנותק
                avr416
                כתב ב נערך לאחרונה על ידי
                #12

                @דוד ל.ט.

                רחמים פתרון יפה, אבל אם כבר לפי איבר מסויים אז הבנתי שזה הname רק שצריך את המאפיין גם של הID. אז אם ככה uniq[i.name].
                וavr416 פעם הבאה חוץ מהבעיה תסביר מה המטרה הרצוייה, והם שייך מקרה של id שונה ושם זהה ומה הדין בכהאי גונא ומדוע 🙂

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

                אבאר קצת יותר, אני בונה דוח שמאפשר למשתמש להציג את התוצאות של כל המבחנים שהתקיימו בתקופה מסויימת, במקצוע מסויים לבחירתו.
                אני מאפשר לו לבחור עבור אילו כיתות או שכבות הוא רוצה להציג את התוצאות, ואני רוצה להציג את המקצוע רק כאשר קיימים עבורו מבחנים באותה תקופה.
                לכן, אני בודק בדטה בייס, באילו מקצועות התקיימות מבחנים בתאריכים הללו, לאותם כיתות, ורק אז אני מציג את שם המקצוע בסלקטבוקס.
                הענין הוא שכיון שהוא יכול לבחור כמה כיתות, אז הנתונים שאני מקבל מהדטה בייס שונים בהרבה פרטים שלא כ"כ משמעותיים כרגע עבורי, ומה שמעניין אותי זה רק באיזה מקצוע התקיים המבחן, דהיינו הID של המקצוע, וגם השם שלו (כדי להציג למשתמש).
                הID והName הם תמיד זהים, ולא משתנים. מה שכן משתנה זה הרבה דברים אחרים, למשל איזה כיתה, איזה מורה וכו'.

                @דוד ל.ט.

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

                מעולה!! באמת לא הבנתי כ"כ איך התכוונת עם הfindIndex הרי לא מעניין אותי כ"כ האינדקס, אלא מעניין אותי שייתן לי את המערך הuniq.
                למה הmap הורס את האינדקסים של המערך המקורי? הרי הוא לא משנה את המקור, הוא בסה"כ מחזיר מערך חדש ע"פ התנאי שאני מעביר לו, לא?
                אז אם כן, מה הבעיה שתוך כדי הmap הוא גם ירוץ על המקורי ויחזיר לי את האינדקס שלו??

                תודה רבה רבה!

                פורסם במקור בפורום CODE613 ב20/07/2017 20:47 (+03:00)

                תגובה 1 תגובה אחרונה
                0
                • dovidD מחובר
                  dovidD מחובר
                  dovid
                  ניהול
                  כתב ב נערך לאחרונה על ידי
                  #13

                  @רחמים

                  הפתרון שכתבתי לעיל עדיף משמעותית מבחינת מהירות [פי 20] על פני שימוש במערך רגיל.
                  ראה ניסוי כאן
                  http://jsben.ch/GYK6P

                  אין ספק שהפתרון שלך יעיל יותר. במקום לסרוק, דורסים לפי אינדקס שלא מתבצע ע"י סריקה אלא ע"י הצבה לאינדקס של אובייקט (שממומש ע"י מילון של hash table). את זה יודעים בלי שום טסט (שאגב עם המון פגמים).
                  אבל איך עושים אם רוצים להשוות לפי שתי מאפיינים? אולי אפשר פשוט לשרשר אותם, לדעתי זה גם יהיה מהר יותר כשהמערך גדול.

                  פורסם במקור בפורום CODE613 ב20/07/2017 21:09 (+03:00)

                  • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                  • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                  תגובה 1 תגובה אחרונה
                  1
                  • dovidD מחובר
                    dovidD מחובר
                    dovid
                    ניהול
                    כתב ב נערך לאחרונה על ידי
                    #14

                    יאהוו הארכת. במילים אחרות באובייקטים יחודיים לפי הID. נקודה.
                    הפתרון של רחמים הוא בהחלט המתאים, אם כי הקוד בשאלה היה יפה ומבריק וטרחתי להעמידו על רגליו.
                    לא מבין מה לא הבנת כי שמתי שפע דוגמאות קוד, ובנוגע לmap הוא מחזיר לך מערך חדש, אבל איללו חשוב לך האיברים המקוריים אין מי שיעשה לך את ההקשר בין האיבר המקורי לאיבר שנשלף ע"י הmap.
                    כמובן כל זה לולי שידעתי שהקובע הוא אך ורק הid.

                    פורסם במקור בפורום CODE613 ב20/07/2017 21:13 (+03:00)

                    • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                    • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                    תגובה 1 תגובה אחרונה
                    1
                    • רחמיםר מנותק
                      רחמיםר מנותק
                      רחמים
                      מורחק
                      כתב ב נערך לאחרונה על ידי
                      #15

                      @דוד ל.ט.

                      @רחמים
                      הפתרון שכתבתי לעיל עדיף משמעותית מבחינת מהירות [פי 20] על פני שימוש במערך רגיל.

                      ראה ניסוי כאן
                      http://jsben.ch/GYK6P

                      אין ספק שהפתרון שלך יעיל יותר. במקום לסרוק, דורסים לפי אינדקס שלא מתבצע ע"י סריקה אלא ע"י הצבה לאינדקס של אובייקט (שממומש ע"י מילון של hash table). את זה יודעים בלי שום טסט (שאגב עם המון פגמים).
                      אבל איך עושים אם רוצים להשוות לפי שתי מאפיינים? אולי אפשר פשוט לשרשר אותם, לדעתי זה גם יהיה מהר יותר כשהמערך גדול.

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

                      פורסם במקור בפורום CODE613 ב20/07/2017 21:19 (+03:00)

                      תגובה 1 תגובה אחרונה
                      0
                      • dovidD מחובר
                        dovidD מחובר
                        dovid
                        ניהול
                        כתב ב נערך לאחרונה על ידי
                        #16

                        לא המון, אלא משהו משמעותי שקפץ לי. הרי אתה רצית להשוות את הסריקה של מערך לבין סריקה של אובייקט, כלומר:

                        arr.indexOf(x)
                        VS
                        object[x]
                        

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

                        פורסם במקור בפורום CODE613 ב20/07/2017 21:29 (+03:00)

                        • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                        • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                        תגובה 1 תגובה אחרונה
                        0
                        • M מנותק
                          M מנותק
                          magicode
                          כתב ב נערך לאחרונה על ידי
                          #17

                          דוד הנה תיקון לטסט. וזה לא משנה את התוצאה.
                          http://jsben.ch/Iqxce

                          פורסם במקור בפורום CODE613 ב21/07/2017 08:49 (+03:00)

                          תגובה 1 תגובה אחרונה
                          1
                          • dovidD מחובר
                            dovidD מחובר
                            dovid
                            ניהול
                            כתב ב נערך לאחרונה על ידי
                            #18

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

                            פורסם במקור בפורום CODE613 ב21/07/2017 10:18 (+03:00)

                            • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                            • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                            תגובה 1 תגובה אחרונה
                            0
                            תגובה
                            • תגובה כנושא
                            התחברו כדי לפרסם תגובה
                            • מהישן לחדש
                            • מהחדש לישן
                            • הכי הרבה הצבעות


                            בא תתחבר לדף היומי!
                            • התחברות

                            • אין לך חשבון עדיין? הרשמה

                            • התחברו או הירשמו כדי לחפש.
                            • פוסט ראשון
                              פוסט אחרון
                            0
                            • דף הבית
                            • קטגוריות
                            • פוסטים אחרונים
                            • משתמשים
                            • חיפוש
                            • חוקי הפורום