按DateTime将数据项分隔到列表中
本文关键字:列表 分隔 数据项 DateTime | 更新日期: 2023-09-27 18:27:06
给定类
public class SomeType
{
public string Name;
public string Field2;
public DateTime CreatedOnDateTime
}
我想取一个List<SomeType>
并将其划分为几个List<SomeType>
,其中每个List都包含具有相等CreatedOnDateTime戳的项。在许多情况下,CreatedOnDateTime是相同的,允许几秒钟的容差会很好。
我可以运行一个LINQ查询N次来创建每个不同的列表。有没有更有效的机制?换句话说,这种类型的查询是否可以使用某种类型的分组机制通过LINQ构建?(当我说分组时,我想象的是RegEx)
为什么要使用正则表达式?这是用于文本模式匹配。听起来你想要ToLookup
:
var lookup = list.ToLookup(x => x.CreatedOnDateTime);
foreach (var entry in lookup)
{
Console.WriteLine("Created: {0}", entry.Key);
foreach (var item in entry)
{
Console.WriteLine(" {0}, {1}", item.Name, item.Field2);
}
}
请注意,这将适用于相同的时间戳。创建这样的"容忍度"是很困难的,但你可以有效地将条目"四舍五入"到几秒钟内:
var lookup = list.ToLookup(x => RoundDownToTwoSeconds(x.CreatedOnDateTime));
...
private static DateTime RoundDownToTwoSeconds(DateTime input)
{
return new DateTime(input.Year, input.Month, input.Day, input.Hour,
input.Minute, (input.Second / 2) * 2,
input.Kind);
}
(如果你想的话,可以想一个更好的名字:)
简单的"容忍"很难的原因是这种情况:
Entry 1: 12:05:14
Entry 2: 12:05:15
Entry 3: 12:05:16
Entry 4: 12:05:17
条目1和条目2仅相隔一秒。。。所以他们应该在同一个桶里。但条目2和条目3仅相隔一秒。。。所以他们也应该在同一个桶里。条目3和4只相隔一秒钟,因此条目4也应该在同一个bucket中。现在,我们在同一个bucket中有条目1和条目4,间隔三秒。
对于公差位(假设您使用的是toLookup/groupBy),您可以在(datetime.ticks/toloranceInTicks)上进行分组。如果你愿意的话,你可能也可以在MS中使用TotalMilliseconds和tolorance。它可能会也可能不会以您想要的方式处理边缘情况,但如果您的数据往往没有太多边缘情况,它应该可以工作。如果应该分组在一起的时间之间的时间差明显大于不应该分组在一起来的时间,这将很好地工作。如果这句话成立,那么你可以在这两个差异之间选择一个宽容度,你就会没事的。然而,如果你的时代相当连续,而且这两个差异相距不远,那么你的容忍度太小或太大的几率就会大大增加。
int precison = 2; //in sec.
var groups = list.GroupBy(s => s.CreatedOnDateTime.Ticks / (TimeSpan.TicksPerMillisecond * 1000 * precison))
.Select(x => new List<SomeType>(x) )
.ToList();
groups
将是List<SomeType>
的列表