Reputation: 23
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
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
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):
Upvotes: 3
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