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

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

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

אינדקס קודם בLINQ

מתוזמן נעוץ נעול הועבר ארכיון code613m
18 פוסטים 3 כותבים 1.1k צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • dovidD מחובר
    dovidD מחובר
    dovid ניהול
    כתב ב נערך לאחרונה על ידי
    #7

    @ארכיטקט

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

    ידידי אתה טועה.
    אתה יכול לבדוק זאת פשוט, שים ברייקפוינט או לוג.

    IEnumerable<MyClass> GetAllBlaBla()
    {
    	Console.WriteLine("start");
    	for (int i = 0; i < 100; i++)
    	{
    		//add here Thread.Sleep to simulate I/O
    		yield return new MyClass { MyProperty = i };
    	}
    }
    

    תראה במקרה שלך זה ידפיס המון פעמים start וחלק מתוכם זה יעשה את כל הלולאה בלי להפסיק.
    אם זה DB זה יריץ כמספר הזה גם שאילתות. תמיד אפשר להמיר לפני זה למערך אבל זה בוגד בלינק - ומסתכן גם בפגיעה ביעילות בזיכרון.
    לא מכיר מה זה LGA.

    פורסם במקור בפורום CODE613 ב22/12/2016 00:38 (+02:00)

    מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

    בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

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

      פורסם במקור בפורום CODE613 ב22/12/2016 00:51 (+02:00)

      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

      בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

        נתנאל הקוד בסטאק הוא בדיוק בשבילך הן לקריאות והן לביצועים.
        הרעיון הוא:

        1. להימנע מלעבור על הפסקאות יותר מפעם אחת כי זו הפעולה היקרה
        2. לאפשר מוניפולציות מחוץ לקוד המעבר אבל שכן יבוצעו בשעת המעבר בשביל לחסוך "לשמור" וגם לבדוק דברים פעמיים.
          מחר אראה לך דוגמה בס"ד.

        פורסם במקור בפורום CODE613 ב22/12/2016 00:55 (+02:00)

        מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

        בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

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

          IEnumerable<Entry> GetAll()
          {
          	PrgClass a = null;
          	PrgClass b = null;
          	PrgClass c = null;
          
          	foreach (var element in xyz) //פה הלולאה על הפסקאות של וורד
          	{
          		a = b;
          		b = c;
          		c = element;
          		yield return new Entry { Before = a, Current = b, After = c } ;
          	}
          }
          
          
          class Entry 
          {
          	public PrgClass Before { get; set; }
          	public PrgClass Current { get; set; }
          	public PrgClass After { get; set; }
          }
          

          מה המעלה בקוד הזה?
          שאחרי זה אם אני כותב:

          var coll = GetAll();
          coll = coll.Where (x => x.After == null || x.After.x > 5); 
          coll = coll.Where(x => x.Before != null && x.Before.y == 6);
          coll = coll.OrderBy (x => x.Current.y);
          
          var result = coll.First();
          

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

          פורסם במקור בפורום CODE613 ב23/12/2016 12:17 (+02:00)

          מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

          בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

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

            פורסם במקור בפורום CODE613 ב23/12/2016 12:23 (+02:00)

            מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

            בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

              תודה רבה! אני עדין באמצע לעכל את כל העושר התכנותי שמתעופף כאן בנדיבות.

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

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

              List<string> ms = new List<string>() { "1","2","545","5445", "reewe" ,"qerwqerqwewrrwer"};
                          IEnumerable<string> result = ms.Where(o => o.Length > 3);
                          int num = ms.Where(o => o.Length > 3).Count();
                          ms.Add("erwereeweweweeeeeeeesdsddddddddd");
                          foreach (var t in result)
                          {
                              Console.WriteLine(t);
                          }
                          Console.WriteLine(num);
              

              הקוד הזה יחזיר 4 תוצאות, אבל ספירה של 3.

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

              פורסם במקור בפורום CODE613 ב24/12/2016 22:14 (+02:00)

              הצטרפות לרשימת התפוצה בעניני תכנות JS , React , Node וכל מיני דברים מענינים כאן :cool:
              https://programing-tips.web.app/

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

                @נתנאל

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

                נכון.

                @נתנאל

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

                • הרבה פעמים מחליטים "לעצור" בפעם הראשונה. למשל Take. או First, Any ועוד.
                • השתלת כל התנאים והמיונים באותו המעבר - הראשון. אם אתה מחזיק איבר ביד, למה שלא תבדוק אם הוא עונה כבר על התנאים?
                • חיסכון החזקת האיברים באיזה מקום - זיכרון. למשל קוד שיקרא רשימת קבצי טקסט ויחזיר אותם בyield וקוד אחר יבקש את שם האיבר/קובץ שמופיע בו מילה מסויימת - בשום שלב הזיכרון לא צריך "לסבול" יותר מתוכן של קובץ בודד.

                @נתנאל

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

                לIEnumerable יש כמה מתודות שמחזירות ערך יחיד (Scalar Value) למשל מזכרוני:
                Count, Sum, Avarage, Any, All, First, Last, Single,
                כל אלה מפעילות את המניה מיידית - ולמעשה מסיימות את שרשרת הIEnumerable.
                לא שייך תוצאות שקריות כי ממילא א"א לשרשר אחריהם - הם לא מחזירים אוסף.

                כמו"כ יש כמה מתודות ייצוא שמשמעותיות למקרה ויידרשו לגשת כמה פעמים לאוסף ואז יש לחסוך במניה (שיכולה להיות מתורגמת לפעולות רציניות מאוד כמו קריאה מDB וכל מה שיכול לעלות בדעתו של מספק האוסף) מיותרת:
                ToArray, ToList, ToDictionary, ToLookup

                @נתנאל

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

                ממש ממש לא. אם המפתח שמספק את האוסף נתן לך List אז אין מה להמיר.
                ואם הוא נתן אוסף שאינו מממש את הIEnumerabl הרי אפשר עדיין לעבור עליו בforeach ושם לשים את הyield. אכן ייתכן שאין הבדל בעלות של הפעלת הforeach ועצירתו מיידית לבין הפעלותו עדך הסוף - זה בהתאם לרמת המפתח שסיפק את האוסף.

                אגב הyield הוא צעיר מלינק. לפני קיומו היו כותבים מחלקה קצת ארוכה שהוציאה את החשק להשקיע.
                גם כיום הקומפיילר מתרגם כל מתודה שמחזירה yield למחלקה בפני עצמה שיורשת מIEnumerable ובתוכה מחלקה של IEnumerator.
                לIEnumerator יש מאפיין בשם Current שמחזיר איבר נוכחי, ומתודה בשם MoveNext שקוראת לאיבר הבא (ומחזירה שלילי בסיום). למעשה זה כל תורת לינק - לתת לסורק האוסף את השליטה מתי לזוז ומתי לפרוש.

                פורסם במקור בפורום CODE613 ב25/12/2016 01:15 (+02:00)

                מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

                  ישר כח גדול!
                  אין אפשרות לגשת ישירות לאוסף הפסקאות בלינק. משהו כזה לא עובד:

                  var test = doc.Paragraphs.where(p=> p.Text=="tt")
                  

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

                  פורסם במקור בפורום CODE613 ב25/12/2016 01:31 (+02:00)

                  הצטרפות לרשימת התפוצה בעניני תכנות JS , React , Node וכל מיני דברים מענינים כאן :cool:
                  https://programing-tips.web.app/

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

                    אכן, אתה צודק ואני טעיתי כמה טעויות...
                    אין foreach בלי IEnumerable, ואכן הParagraps של וורד כן מממש IEnumerable.
                    אלא שמתודות ההרחבה של IEnumerable (כמו Wher וכל היתר) עובדים רק במימוש IEnumerable<T> כלומר הגירסה הגנרית.
                    ופה הטעות הגדולה: צריך סה"כ להמיר מIEnumerable לגירסה הגנרית, ובשביל זה אתה בכלל לא צריך לכתוב את הforeach עם yield.
                    יש שתי מתודות שממירים IEnumerable מסוג כלשהוא או ללא סוג כלל כמו אצלנו לאוסף גנרי מסוג אחר. אחד Cast והשני TypeOf.
                    שניהם ממומשים פשוט עם לולאה על האוסף עם yield, הCast פשוט מציב סוגריים לפני האיבר ומנסה לעשות קאסטינג - כלומר הוא מניח שזה בודאי מהסוג שציינו. ואילו הTypeOf בודק על כל איבר באמצעות is אם זה הסוג שצויין ומחזיר רק איבר שהתשובה לגביו חיובית.
                    במקרה שלך Cast זה מעולה. אתה פשוט כותב ככה:

                    var test = doc.Paragraphs.Cast<Microsoft.Office.Interop.Word.Paragraph>();
                    test = test.Where (t => t.Range.Text.Length > 200);
                    

                    פורסם במקור בפורום CODE613 ב25/12/2016 10:44 (+02:00)

                    מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                    בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

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

                      פורסם במקור בפורום CODE613 ב25/12/2016 11:12 (+02:00)

                      הצטרפות לרשימת התפוצה בעניני תכנות JS , React , Node וכל מיני דברים מענינים כאן :cool:
                      https://programing-tips.web.app/

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

                        @נתנאל

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

                        קוראים לזה projecting.
                        גם זה אפשר בlinq. המתודה Select (ולמעשה עוד כמה מתודות) מחזירים טיפוס חדש. למעשה זה בדיוק קיצור למה שעשית - foreach עם yield.
                        דוגמה לselect:

                        var coll = new int[] { 1, 2, 23, 4};
                        var query = coll.Select(c => new MyClass(c));
                        

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

                        כל הדוגמאות של שימוש במתודות ההרחבה נקראות Fluent Syntax, בשביל הקריאות כדאי לפעמים להשתמש בquery syntax הנה דוגמה:

                        var collAsMyclass = from item in coll
                        					where item > 2
                        					select new MyClass(item);
                        			
                        			
                        var filtered = from item in collAsMyclass
                                       where item.MyProperty > 15
                                       select item;
                        

                        פורסם במקור בפורום CODE613 ב25/12/2016 12:22 (+02:00)

                        מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                        בכל נושא אפשר ליצור קשר dovid@tchumim.com

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

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

                          public IEnumerable<mypara> GetAllParas(word.Document doc) {
                                      for (int i = 1; i <= doc.Paragraphs.Count; i++)
                                      {
                                          yield return new mypara(doc.Paragraphs[i], i == 1 ? null : doc.Paragraphs[i - 1], i == doc.Paragraphs.Count ? null : doc.Paragraphs[i + 1]);
                                      }
                          

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

                          פורסם במקור בפורום CODE613 ב25/12/2016 12:43 (+02:00)

                          הצטרפות לרשימת התפוצה בעניני תכנות JS , React , Node וכל מיני דברים מענינים כאן :cool:
                          https://programing-tips.web.app/

                          תגובה 1 תגובה אחרונה
                          0

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

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

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