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\$
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\$
  • \$\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 Oct 1 '14 at 19:17
  • \$\begingroup\$ @JamesTown: I changed by answer after thinking about it a bit more \$\endgroup\$ – ChrisWue Oct 1 '14 at 19:42
  • \$\begingroup\$ The code posted is throwing a "; expected" on: Offer = x, \$\endgroup\$ – JamesTown Oct 1 '14 at 21:04
  • \$\begingroup\$ It's missing a new \$\endgroup\$ – ChrisWue Oct 1 '14 at 21:32
  • \$\begingroup\$ You mean the new DateTime in the line below? That's there. Sorry if I'm missing something. \$\endgroup\$ – JamesTown Oct 1 '14 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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