Looking for a C # algorithm to capture duplicate elements from a collection of DateTime objects (factoring by both date and time)?

I have a collection of DateTime objects. I need to parse subcollections from this source list in order to capture related items based on repetition. Therefore, I need to take this single original collection:

 var collectionOfDateTime = GetDateTimeCollection(); 

and translate this into a list of DateTime collections, where each collection includes a set of dates from the first list that follows a specific recurrence pattern.

In my examples below, I do not include time, but in real demand, these elements have Date and Time elements for them. So, for example, the dates should be 7 days apart, but also the same (one time February 3 at 11 am does not correspond to February 10 at 3 pm, but it corresponds to February 10 at 11 am)

For example, suppose my recurrence pattern is “Weekly” (in other cases, it can be “Monthly”), and my collection of dates looks like this:

  var date1 = DateTime.Today.AddHours(8); var date2 = DateTime.Today.AddWeeks(1).AddHours(8); var date3 = DateTime.Today.AddDays(3); var date4 = DateTime.Today.AddWeeks(8).AddHours(6); var collectionOfDateTime = new List<DateTime>() { date1, date2, date3, date4 }; 

I need a function (allowing it to StripOutSubCollections() ) to pass to collectionOfDateTime and the fact that it is "Weekly" and return a single collection that includes date1 , date2 (since they are all part of the same weekly slot). Note date3 is not suitable, and date4 is also not suitable, since the clock does not match with the others

As another example, to help prove this requirement, if the entrance to the original collection was as follows:

  var date1 = DateTime.Today; var date2 = DateTime.Today.AddWeeks(1); var date3 = DateTime.Today.AddDays(3); var date4 = DateTime.Today.AddWeeks(8); var date5 = DateTime.Today.AddDays(3).AddWeeks(2); var collectionOfDateTime = new List<DateTime>() { date1, date2, date3, date4, date5 }; 

I would like this function to return 2 lists (one list with date1 , date2 and date4 ) and another list with date3 and date5 .

Let me know if I need additional examples to formulate requirements? Please note that it is possible that one of the dates may fall into several output lists, which is fine.

I can convert weekly to the number 7 and loop through each element, from the first element to the end, then the second element to the end, then the third element, etc., but I would like to see if there was another elegant way

0
source share
3 answers

If I understand your question correctly, are you trying to "trim" DateTime values ​​by the day of the week?

If so, something like this should do this:

 var byDayOfWeek = collectionOfDateTime.GroupBy(dt => dt.DayOfWeek); // Optionally convert to a dictionary by day of week var asDict = byDayOfWeek.ToDictionary(grp => grp.Key, grp => grp.ToList()); foreach(var kvp in asDict) { Console.WriteLine("Day:" + kvp.Key); foreach (var value in kvp.Value) { Console.WriteLine(value); } } 

Output:

 Day:Thursday 2/21/2013 12:00:00 AM 2/28/2013 12:00:00 AM 4/18/2013 12:00:00 AM Day:Sunday 2/24/2013 12:00:00 AM 

EDIT: for several rules grouping by rules:

 public enum ChunkType { Weekly, Monthly, Yearly } public IEnumerable<IEnumerable<DateTime>> ChunkDates(IEnumerable<DateTime> collection, ChunkType chunkBy) { switch(chunkBy) { case ChunkType.Weekly: // roughly equals by day of week return collection.GroupBy(dt => dt.DayOfWeek).Select(grp => grp.ToList()); case ChunkType.Monthly: // Trickier - assume by ordinal day of month? return collection.GroupBy(dt => dt.Day).Select(grp => grp.ToList()); case ChunkType.Yearly: // Trickier - assume by ordinal day of year? return collection.GroupBy(dt => dt.DayOfYear).Select(grp => grp.ToList()); } return new[]{ collection }; } var date1 = DateTime.Today; var date2 = DateTime.Today.AddDays(7); var date3 = DateTime.Today.AddDays(3); var date4 = DateTime.Today.AddDays(8*7); var collectionOfDateTime = new List<DateTime>() { date1, date2, date3, date4}; foreach(var type in new [] { ChunkType.Weekly, ChunkType.Monthly, ChunkType.Yearly }) { Console.WriteLine("Now grouping by:" + type); var grouped = ChunkDates(collectionOfDateTime, type); foreach(var groupOfDates in grouped) { Console.WriteLine("New group!"); foreach (var value in groupOfDates) { Console.WriteLine(value); } } } 

Output:

 Now grouping by:Weekly New group! 2/21/2013 12:00:00 AM 2/28/2013 12:00:00 AM 4/18/2013 12:00:00 AM New group! 2/24/2013 12:00:00 AM Now grouping by:Monthly New group! 2/21/2013 12:00:00 AM New group! 2/28/2013 12:00:00 AM New group! 2/24/2013 12:00:00 AM New group! 4/18/2013 12:00:00 AM Now grouping by:Yearly New group! 2/21/2013 12:00:00 AM New group! 2/28/2013 12:00:00 AM New group! 2/24/2013 12:00:00 AM New group! 4/18/2013 12:00:00 AM 
+2
source

Use LINQ

Try it (something like this is LINQesque pseudo-code)

 var datecollections = from d in collectionOfDateTime group d by d.DayOfWeek into g select new { Day = g.Key, Date = g }; 

Let him go and see where he will deliver you ...

0
source
 var dict = new Dictionary<int, List<DateTime>>(); foreach (var date in collectionOfDateTime) { if (dict.Contains(date.DayOfWeek)) { dict[date.DayOfWeek].Add(date); } else { dict.Add(date.DayOfWeek, new List<Date> { date }); } } 
0
source

All Articles