0
\$\begingroup\$

I'm working on a Xamarin application and I'm presenting a list of objects in a TableView that are grouped by a specific property of the object.

The property is a date. For each distinct date, I am creating a table section with a header containing said date. Below is the working code to accomplish this, but It's not very elegant.

    var trades = new List<ViewCell>();
    Dictionary<string, List<ViewCell>> dict = new Dictionary<string, List<ViewCell>>();

    // organizing each object into a dictionary with a key that
    // represents the table header and value for the sections objects
    foreach (var item in completed)
    {
        var date = item.DateClosed.ToString("MMMM dd yyyy");

        if (dict.ContainsKey(date))
        {
            dict[date].Add(new TradeCell(item));
        }
        else {
            dict[date] = new List<ViewCell> { new TradeCell(item) };
        } 
    }

    // looping through the resulting dict to assemble the table             
    foreach (KeyValuePair<string, List<ViewCell>> entry in dict) 
        _table.Root.Add(new TableSection(entry.Key) { entry.Value });

My Question

This gets the job done but I was hoping for a more elegant approach, perhaps using linq?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Don't make an assumption about the performance - I don't see anything outrageous there. Come back to it if you can prove it's a pain point. \$\endgroup\$
    – RobH
    Commented Sep 23, 2016 at 9:22
  • \$\begingroup\$ @RobH thanks, I guess more than performance I felt like there might be a cleaner way to do this. If I revise my question, do you think a more elegant solution is possible, perhaps using linq? If not, I'll go ahead and vote to close this question. \$\endgroup\$ Commented Sep 23, 2016 at 11:56
  • \$\begingroup\$ That's a different question entirely ;) you can use GroupBy to do what you want. \$\endgroup\$
    – RobH
    Commented Sep 23, 2016 at 14:56
  • \$\begingroup\$ @RobH I'm not super familiar with all of the possibilities of linq, I've updated my question. \$\endgroup\$ Commented Sep 23, 2016 at 14:58

1 Answer 1

2
\$\begingroup\$

You asked for a more elegant approach... This is certainly more concise:

var dict = completed
    .GroupBy(
        item => item.DateClosed.ToString("MMMM dd yyyy"), // Key selector
        item => new TradeCell(item)) // Value selector
    .ToDictionary(g => g.Key, g => g.ToList());

However, you don't actually need the dictionary (that's just to keep the same behaviour as the foreach). This should do the job:

foreach (var groupOfCells in completed.GroupBy(item => item.DateClosed.ToString("MMMM dd yyyy"), item => new TradeCell(item)))
{
    _table.Root.Add(new TableSection(groupOfCells.Key) { groupOfCells .ToList() });
}

Remember not to abbreviate names. dict doesn't mean anything to anyone.

I'd also suggest grouping by DateClosed.Date and converting to a string in your UI layer. I don't know if you need it, but it's much harder to localise if you include hard coded format strings all over the place.

\$\endgroup\$
1
  • \$\begingroup\$ You're the best, this is exactly what I was looking for \$\endgroup\$ Commented Sep 23, 2016 at 15:27

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.