我有一组DateTime
个对象。我需要从原始列表中“解析”子集合以根据重现来获取相关项目。所以我需要采用这个原始集合:
var collectionOfDateTime = GetDateTimeCollection();
并将其转换为DateTime
个集合的列表,其中每个集合包含一组特定重复模式后的第一个列表中的日期。
在下面的示例中,我不包括时间,但在实际要求中,这些项目都包含日期和时间元素。因此,例如,日期需要相隔7天但也是同一时间(2月3日上午11点的一次与下午3点的第10天不匹配,但它确实与2月10日上午11点匹配)
例如,假设我的重复模式是“每周”(在其他情况下可能是“每月”),我的日期集合如下所示:
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 };
我想要一个函数(让我们称之为StripOutSubCollections()
)来传递collectionOfDateTime
以及它的“Weekly”这一事实并返回一个包含date1
的集合,{{1 (因为它们都是同一周插槽的一部分)。注意date3不适合,而date4也不合适,因为小时与其他小时不匹配
另一个帮助证明要求的例子,如果原始集合的输入是这样的:
date2
我希望此函数返回2个列表(一个列表包含 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 };
,date1
和date2
),另一个列表包含date4
和date3
如果我需要更多示例来阐明要求,请告诉我们?请注意,其中一个日期可能属于多个输出列表,这很好。
我可以将每周转换为数字7并循环执行从第一个项目到结尾的每个项目,然后是第二个项目到结束,然后是第三个项目,等等但是想看看是否还有更多项目优雅的方式
答案 0 :(得分:2)
如果我理解你的问题,那你试图按周划分“DateTime
值?”
如果是这样的话,应该这样做:
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);
}
}
输出:
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
编辑:对于多个“分组依据”规则:
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);
}
}
}
输出:
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
答案 1 :(得分:0)
使用LINQ
尝试(类似,这是LINQesque伪代码)
var datecollections = from d in collectionOfDateTime
group d by d.DayOfWeek into g
select new { Day = g.Key, Date = g };
放手一搏,看看它在哪里......
答案 2 :(得分:0)
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 });
}
}