Nuria
Nuria

Reputation: 27

Dictionary group by value

I have a TimeEntry class and a Dictionary with the Id as Key and the other Properties as Value. Now i want to group the dictionary by the value of Category

 class TimeEntry
    {
        public int Id { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public string Task { get; set; }
        public string Category { get; set; }

        public override string ToString()
        {
            return string.Format($"Start Time: {StartTime}, EndTime: {EndTime}, Task: {Task}, Category {Category}");
        }
    }
private readonly IDictionary<int, TimeEntry> _timeEntries;

I want to display something like this:

Household 
   00:30:00 do something
   00:30:00 do some stuff
work 
   01:30:00 go to work 
   00:30:00 to some work thing

it has to be grouped by category

Upvotes: 0

Views: 128

Answers (3)

Ivvan
Ivvan

Reputation: 730

First of all, if you want to do some calculations with date (start and end), you will need to change it to DateTime:

public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }

Then if you prefer more imperative way:

foreach (var group in _timeEntries.GroupBy(x => x.Value.Category))
{
    Console.WriteLine(group.Key);
    foreach (var entry in group)
    {
        var timespan = entry.Value.EndTime - entry.Value.StartTime;
        Console.WriteLine($"  {timespan.ToString(@"hh\:mm\:ss")} {entry.Value.Task}");
    }
}

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

You are looking for GroupBy in Linq, e.g.

using System.Linq;

...

_timeEntries                       // from given dictionary we want
  .Values                          //   Values
  .GroupBy(item => item.Category)  //   Grouped By Category

For instance:

string report = string.Join(Environment.NewLine, _timeEntries
  .Values
  .GroupBy(item => item.Category)
//.OrderBy(group => group.Key, StringComparer.CurrentCultureIgnoreCase)
  .Select(group => 
     $"{group.Key}\r\n  {string.Join("\r\n  ", group.Select(item => $"{item.StartTime} {item.Task}"))}"));

The only difficulty is to represent group within final Select

Upvotes: 3

Walczak Jakub
Walczak Jakub

Reputation: 92

Something like this?

_timeEntries.OrderBy(x => x.Value.Category).ThenBy(x => x.Value.StartTime)

Category -> StartTime.

You can add as many as you need to:

_timeEntries.OrderBy(x => x.Value.Category).ThenBy(x => x.Value.StartTime).ThenBy(x => x.Value.EndTime).ThenByDescending(x => x.Value.Task)

Category -> StartTime -> EndTime -> (Descending) Task etc

Upvotes: 0

Related Questions