הסתרת קטגוריות בפוסטים ודוגמה לשימוש באוספים

image_thumb_9

כחלק מתהליך העבודה על בלוג נתקלתי בבעיה הזאת. אחד מהפוסטים שלי הראה שהוא שייך לקטגוריות הנ”ל:

Featured, Software Reviews

אבל אני משתמש בקטגוריה  Featured לניהול תוכן והיא לא אמורה להיות מוצגת, ולכן הייתי צריך להסתיר אותה.

אחד היתרונות בלהריץ את הבלוג של עצמך הוא שאין בעיה לעשות תיקונים כאלה.

זוהי הפונקציה שמייצרת המחרוזת של הקטגוריות:  (PostViewBase.cs – שורה 153):

protected virtual string CategoryLinks(string separator)
{
    string[] keywords = new string[Post.Categories.Count];
    string link = "<a href=\"{0}{1}.aspx\">{2}</a>";
    string path = VirtualPathUtility.ToAbsolute("~/category/");
    for (int i = 0; i < Post.Categories.Count; i++)
    {
        if (Category.Categories.Contains((Category)Post.Categories[i]))
        {
            string category = Category.GetCategory(Post.Categories[i].Id).Title;
            keywords[i] = string.Format(CultureInfo.InvariantCulture, link, path, Utils.RemoveIllegalCharacters(category), category);
        }
    }
    return string.Join(separator, keywords);
}

 

כדי להוריד את קטגורית Featured, הוספתי את הבדיקה בשורה מספר 10 (בבלוג שלי קטגוריות שלא מיועדות לתצוגה התיאור שלהן הוא נקודותיים):

protected virtual string CategoryLinks(string separator)
{
    string[] keywords = new string[Post.Categories.Count];
    string link = "<a href=\"{0}{1}.aspx\">{2}</a>";
    string path = VirtualPathUtility.ToAbsolute("~/category/");
    for (int i = 0; i < Post.Categories.Count; i++)
    {
        if (Category.Categories.Contains((Category)Post.Categories[i]))
        {
            if (Category.GetCategory(Post.Categories[i].Id).Description.StartsWith(":")) continue;
            string category = Category.GetCategory(Post.Categories[i].Id).Title;
            keywords[i] = string.Format(CultureInfo.InvariantCulture, link, path, Utils.RemoveIllegalCharacters(category), category);
        }
    }

    return string.Join(separator, keywords);
}

 

כשהרצתי את הקוד החדש זה מה שקיבלתי:

, Software Reviews

כלומר הוא כן הוריד את הקטגוריה הלא רצויה, אבל הוא השאיר את הפסיק.

אבל למה זה קורה? הרי השימוש ב- Join אמור למנוע דברים כאלה!

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

הבעיה היא לא ב- Join, אלא במערך שאנחנו מעבירים לה. המערך מכיל עדיין שני איברים – האחרון פשוט הוא מחזרות ריקה. Join לא עושה בדיקה אם המחרוזת ריקה או לא – אם הוא קיים הוא ישרש אותו למחרוזת, אפילו אם הוא ריק.

עכשיו נשאלת השאלה איך זה קרה שהאיבר האחרון ריק? הרי בלולאה אנחנו מדלגים הלאה אם לא צריך להיתייחס לקטגוריה!

אם תיסתכלו בשורה הראשונה, תראו את מקור הבעיה; ההצהרה:

 

string[] keywords = new string[Post.Categories.Count];

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

טוב אז מה עושים?

מחשבה ראשונה היתה לעבור על המערך ולמחוק את האינרים הריקים. אבל זה לא כזה פשוט לביצוע:

במקרה שהאיבר הריק הוא בסוף המערך, קל יחסית “להקטין” את גודל המערך ובכך להוציא אותו החוצה.

אבל מה יקרה אם האיבר הריק יהיה באמצע המערך? אין דרך קלה למחוק – או להוציא – איבר מאמצע מערך. רוב הדרכים כוללות יצירת מערכים זמניים אחרים ואנחנו ממש לא רוצים לחגיע (או יותר נכון – לחזור לשם).

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

למה שלא נתחיל עם מערך ריק ונוסיף לתוכו את הקטגוריות שאנחנו רוצים?

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

אבל בשביל מה לנו להיתעסק בכלל בכל הדבר הזה? בשביל מה המציאו את האוספים- (Collections)?

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

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

בואו נחזור לפנוקציה שלנו, והפעם נחליף את המערך באוסף:

protected virtual string CategoryLinks(string separator)
{
    List<string> keywords = new List<string>();
    string link = "<a href=\"{0}{1}.aspx\">{2}</a>";
    string path = VirtualPathUtility.ToAbsolute("~/category/");
    for (int i = 0; i < Post.Categories.Count; i++)
    {
        if (Category.Categories.Contains((Category)Post.Categories[i]))
        {
            if (Category.GetCategory(Post.Categories[i].Id).Description.StartsWith(":")) continue;
            string category = Category.GetCategory(Post.Categories[i].Id).Title;
            keywords.Add(string.Format(CultureInfo.InvariantCulture, link, path, Utils.RemoveIllegalCharacters(category), category));
        }
    }

return string.Join(separator, keywords.ToArray());
}

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

List<string> keywords = new List<string>();

הגדרת keywords כאוסף מסוג מחרוזת (אין צורך לתת לו גודל התחלתי)

keywords.Add(string.Format(CultureInfo.InvariantCulture, link, path, Utils.RemoveIllegalCharacters(category), category));

במקום הכנסה למקום קבוע למערך – הוספה הקטגוריה לאוסף

return string.Join(separator, keywords.ToArray());

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

וזהו! ככה ניראת התוצאה אחרי המעבר לאוספים:

Software Reviews

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

אני לא יודע למה החברה מ- BlogEngine.net בחרו להישתמש פה במערך ולא באוסף; כנראה בשביל הפשטות – אבל שימו לב אילו סיבוכים יכולים להיגרם אחר כך אם אתם רוצים לעשות פעולות בסיסיות אפילו עם המערך, וחוץ מזה – האם השימוש באוסף היה באמת מסובך מדי?

אני מקווה שהראתי לכם איך השימוש באוספים (Collections)  יכול להפוך את החיים שלכם לקלים יותר, וסוף סוף יגרום לכם לוותר על המערכים המיושנים..

שתפו את הפוסט:
תגיות: ,

זכויות יוצרים

cc88x31 תכני הבלוג המקוריים חופשיים לשימוש תחת רשיון Creative Commons מסוג ייחוס-שיתוף זהה (CC-by-share alike) (הרשיון באנגלית, עברית), אלא אם צוין אחרת.

התגובות המתפרסמות בבלוג חופשיות גם הן לשימוש תחת רשיון Creative Commons מסוג ייחוס-שיתוף זהה (CC-by-share alike). אם אינכם מעוניינים שתגובותיכם יקבלו רשיון זה – אל תגיבו כאן.

תכני הבלוג הלא-מקוריים מופיעים כאן ברשות או בשימוש הוגן.

השארו מעודכנים

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

RSS Feed RSS - פוסטים RSS Feed RSS - תגובות

אודות האתר

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

ערן הרץ הוא היוצר של VoiceOfLogic. מתגורר בהוד השרון ועובד בתחום ההיטק בפיתוח ווב.