I have a list of dates and I want to group by items that are consecutive days
so if in the list I have the following dates:
Dec 31, 2013
Jan 1, 2014
Jan 2, 2014
Feb 1, 2014
Feb 2, 2014
Feb 16, 2014
Mar 13, 2014
I want to come up with a way to group this so I get:
Group 1:
Dec 31, 2013
Jan 1, 2014
Jan 2, 2014
Group 2:
Feb 1, 2014
Feb 2, 2014
Group 3:
Feb 16, 2014
Group 4: Mar 13, 2014
as you can see, the grouping is based on items that are consecutive days.
What is the best way in C#, to take this list and transform them into these groups?
In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...
C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.
This should do the trick if you're looking for something very quick and dirty.
IEnumerable<DateTime> dates = ...;
var groups = dates
.Distinct()
.OrderBy(date => date)
.Select((date, i) => new { date, key = date.Subtract(TimeSpan.FromDays(i)) })
.GroupBy(tuple => tuple.key, tuple => tuple.date);
The logic of the following code is pretty straight forward, sort the list and check if the days delta is greater than 1. If it is, create a new group for it:
Create the dates for testing:
//Dates for testing
List<DateTime> dates = new List<DateTime>()
{
new DateTime(2013,12,31),
new DateTime(2014,2,2),
new DateTime(2014,1,1),
new DateTime(2014,1,2),
new DateTime(2014,2,1),
new DateTime(2014,2,16),
new DateTime(2014,3,13),
};
And create the groups:
dates.Sort();
//this will hold the resulted groups
var groups = new List<List<DateTime>>();
// the group for the first element
var group1 = new List<DateTime>(){dates[0]};
groups.Add(group1);
DateTime lastDate = dates[0];
for (int i = 1; i < dates.Count; i++)
{
DateTime currDate = dates[i];
TimeSpan timeDiff = currDate - lastDate;
//should we create a new group?
bool isNewGroup = timeDiff.Days > 1;
if (isNewGroup)
{
groups.Add(new List<DateTime>());
}
groups.Last().Add(currDate);
lastDate = currDate;
}
And the output:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With