Hari Mohan
Hari Mohan

Reputation: 23

Group and filter from list of objects c#

I have a list of type class. I want to group by and filter based on one of the members of class. My code looks like below:

public class SP 
{
    public int ID { get; set; } 
    public string Name { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; }
} 

List<sp> splist = new List<sp>();

 ID    Name            StartDate     EndDate
6025  'Bob'          '2010-05-10'    '2015-08-20'
6026  'Jessica'      '2012-01-15'    '2013-04-13'
6028  'Christina'    '2010-05-10'    '2016-11-20'
6029  'Chris'        '2011-03-20'    '2014-08-19'
6030  'James'        '2011-03-20'    '2012-08-28'
6031  'Morris'       '2009-06-12'    '2017-01-20'

I want to GroupBy and prepare a report based on the 'StartDate' property. The actual value of StartDate will be known during runtime only.

Please help me with list group by with runtime value. I would like to have resultset as,

On first iteration,

6025 'Bob' '2010-05-10' '2015-08-20'
6028 'Christina' '2010-05-10' '2016-11-20'
Second
6026 'Jessica' '2012-01-15' '2013-04-13'
Third
6029 'Chris' '2011-03-20' '2014-08-19'
6030 'James' '2011-03-20' '2012-08-28'
and on fourth
6031 'Morris' '2009-06-12' '2017-01-20'

Upvotes: 1

Views: 3099

Answers (2)

Rufus L
Rufus L

Reputation: 37060

You haven't specified a filter for your class, but in your expected output it looks like you just want to use grouping and not filtering (since all the results are in the output, nothing was filtered).

One change I made in your SP class was to override the ToString() method so the class has a friendly way to display itself in the output:

public class SP
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public override string ToString()
    {
        var formattedName = (Name + " ").PadRight(13, '.');
        return $"{ID}: {formattedName} Started on: {StartDate:d}, Ended on: {EndDate:d}";
    }
}

Then I added a list of the sample data you provided:

// Sample data
var newlist = new List<SP>
{
    new SP {ID = 6025, Name = "Bob", StartDate = DateTime.Parse("2010-05-10"),
        EndDate = DateTime.Parse("2015-08-20")},
    new SP {ID = 6026, Name = "Jessica", StartDate = DateTime.Parse("2012-01-15"),
        EndDate = DateTime.Parse("2013-04-13")},
    new SP {ID = 6028, Name = "Christina", StartDate = DateTime.Parse("2010-05-10"),
        EndDate = DateTime.Parse("2016-11-20")},
    new SP {ID = 6029, Name = "Chris", StartDate = DateTime.Parse("2011-03-20"),
        EndDate = DateTime.Parse("2014-08-19")},
    new SP {ID = 6030, Name = "James", StartDate = DateTime.Parse("2011-03-20"),
        EndDate = DateTime.Parse("2012-08-28")},
    new SP {ID = 6031, Name = "Morris", StartDate = DateTime.Parse("2009-06-12"),
        EndDate = DateTime.Parse("2017-01-20")},
};

Now, you can group this list by StartDate with a single line:

// Group on Property 'StartDate'
var groupedList = newlist.GroupBy(a => a.StartDate).ToList();

And finally, to look at the members of each group, we can cast each group to a List, which will be a list of the SP objects in the group. We can also reference the group.Key, which is the property that we grouped by (StartDate). So displaying the groups might look something like:

foreach (var group in groupedList)
{
    var groupMembers = group.ToList();

    Console.WriteLine($"Members who have a Start Date of: {group.Key:d}");
    Console.WriteLine("--------------------------------------------");
    Console.WriteLine($" - {string.Join("\n - ", groupMembers)}");
    Console.WriteLine("\n");
}

Output

enter image description here


Now, if you want to sort the group by the StartDate (which is the group.Key), then you can add an OrderBy clause:

// GroupBy and OrderBy Property 'StartDate'
var groupedList = newlist.GroupBy(a => a.StartDate).OrderBy(a => a.Key).ToList();

And now your output will be sorted, with the oldest start dates appearing first (you could change OrderBy to OrderByDescending if you want the most recent StartDate to come first):

enter image description here

Upvotes: 3

NetMage
NetMage

Reputation: 26926

To use group by and convert to a list is easy:

var newlist = (from ar in db.A group ar by ar.D select ar).ToList();

Upvotes: 1

Related Questions