4
\$\begingroup\$

I've been working on an older project with framework is 3.5 as the target. There is a new user control that displays a list of data from a web service. I hit the web service (Soap/XML) and deserialize the data into a list of a custom model/class (this is in a helper class outside the user control).

Back in the user control code behind, I'm looping through the data and displaying it using a HtmlTextWriter. Here is an example of some of the code (simplified):

        var sb = new StringBuilder();
        using (var writer = new HtmlTextWriter(new StringWriter(sb)))
        {
            foreach  (
                var month in
                    courses.SelectMany(x => x.Offerings)
                        .Where(x => !string.IsNullOrEmpty(x.StartDate))
                        .Select(x => DateTime.Parse(x.StartDate))
                        .Select(x => new DateTime(x.Year, x.Month, 1))
                        .Distinct()
                        .OrderBy(x => x.Year)
                        .ThenBy(x => x.Month)
                        .ToList())
            {

            //some display code using the writer

                foreach (var offering in
                    courses.SelectMany(x => x.Offerings)
                        .Where(x => !string.IsNullOrEmpty(x.StartDate))
                        .Where(
                            x =>
                                DateTime.Parse(x.StartDate).Year == month.Year
                                && DateTime.Parse(x.StartDate).Month == month.Month)
                        .OrderBy(x => DateTime.Parse(x.StartDate))
                        .ToList())
                {
                    //more display code using the writer
                }
            }
        }
        thisisadiv.InnerHtml = sb.ToString();

The HTML markup is a design that was already in place somewhere else so I chose not to change it at all in the interest of time.

Is there a more efficient way of looping through the classes/data that I could benefit from? I'm currently not seeing any speed issues but want to make sure I'm using an adequate technique.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

Actually reviewing your question again it looks like what you are trying to do is to group all offerings by the same year and month and then iterate over each offering. Hence a GroupBy query is probably what you want:

foreach (
    var offerings in
        courses.SelectMany(x => x.Offerings)
            .Where(x => !string.IsNullOrEmpty(x.StartDate))
            .Select(x =>
                    new {
                        Offer = x,
                        StartDateMonth = new DateTime(DateTime.Parse(x.StartDate).Year, DateTime.Parse(x.StartDate).Month, 1)
                    })
            .GroupBy(x => x.StartDateMonth)
            .OrderBy(g => g.Key))
{

    //some display code using the writer
    // offerings will be a group of offerings which have the StartDate in the same year/month

    foreach (var offering in offerings.Select(o => o.Offer))
    {
        // iterate over all offers in the group
    }
}

Not sure if there is a nice effective way to avoid the double parsing.

\$\endgroup\$
7
  • \$\begingroup\$ Awesome thank you! Would you suggest converting StartDate string to a DateTime in the constructor of the course class (courses is a list of course)? Can you explain what you mean by "A simple Orderby (x => x)"? \$\endgroup\$
    – JamesTown
    Commented Oct 1, 2014 at 19:17
  • \$\begingroup\$ @JamesTown: I changed by answer after thinking about it a bit more \$\endgroup\$
    – ChrisWue
    Commented Oct 1, 2014 at 19:42
  • \$\begingroup\$ The code posted is throwing a "; expected" on: Offer = x, \$\endgroup\$
    – JamesTown
    Commented Oct 1, 2014 at 21:04
  • \$\begingroup\$ It's missing a new \$\endgroup\$
    – ChrisWue
    Commented Oct 1, 2014 at 21:32
  • \$\begingroup\$ You mean the new DateTime in the line below? That's there. Sorry if I'm missing something. \$\endgroup\$
    – JamesTown
    Commented Oct 1, 2014 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.