给定课程
public class SomeType
{
public string Name;
public string Field2;
public DateTime CreatedOnDateTime
}
我想取一个List<SomeType>
并将其分成几个List<SomeType>
,其中每个List包含具有相等CreatedOnDateTime标记的项目。在许多情况下,CreatedOnDateTime将是相同的,允许几秒钟的容差会很好。
我可以多次运行LINQ查询来创建每个不同的列表。有更有效的机制吗?换句话说,使用某种类型的分组机制可以使用LINQ构建这种类型的查询吗? (当我说分组时,我想象一个RegEx)
答案 0 :(得分:5)
为什么要使用正则表达式?那是文本模式匹配。听起来你想要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也应该在同一个桶中。现在我们在同一个桶中分别有3秒和4秒的条目。
答案 1 :(得分:0)
对于容差位(假设您正在使用toLookup / groupBy),您可以分组(datetime.ticks / toloranceInTicks)。如果您愿意,也可以在MS中使用TotalMilliseconds和tolorance。它可能会或可能不会以您想要的方式处理边缘情况,但如果您的数据往往没有很多边缘情况,它应该可以工作。如果应该组合在一起的时间之间的时间差异明显大于不应该组合在一起的时间,那么这将很好地工作。如果那个陈述成立,那么你可以选择这两个差异之间的公差,你会没事的。但是,如果你的时间相当连续,并且两个差异相差不大,那么你的容忍度太小或太大的可能性就会增长很多。
答案 2 :(得分:0)
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>