有没有办法根据数据元素之间的差异对数据元素进行分组?
List<Message> messages = new List<Message>();
class Message
{
private DateTime Date { get; set; }
private string Text { get; set; }
}
消息日期中的示例数据:
14.3 2014 20:28:15
14.3 2014 20:32:17
14.3 2014 20:37:25
14.3 2014 22:38:43
14.3 2014 20:40:23
14.3 2014 20:42:07
14.3 2014 20:43:54
14.3 2014 20:52:26
14.3 2014 20:53:41
14.3 2014 20:55:37
14.3 2014 20:58:44
我需要LINQ
这样的群组查询。如果没有记录六分钟,将启动一个新组。
Group 1
14.3 2014 20:28:15
14.3 2014 20:32:17
Group 2
14.3 2014 20:37:25
14.3 2014 20:38:43
14.3 2014 20:40:23
14.3 2014 20:42:07
14.3 2014 20:43:54
Group 3
14.3 2014 20:52:26
14.3 2014 20:53:41
14.3 2014 20:55:37
14.3 2014 20:58:44
答案 0 :(得分:1)
当然,我们可以创建自己的GroupWhile
方法,让我们在条件满足时对项目进行分组:
var query = messages.GroupWhile((prev, current) =>
prev.Date.AddMinutes(6) >= current.Date));
GroupWhile
可以这样实现:
public static IEnumerable<IEnumerable<T>> GroupWhile<T>(
this IEnumerable<T> source, Func<T, T, bool> predicate)
{
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
yield break;
List<T> list = new List<T>() { iterator.Current };
T previous = iterator.Current;
while (iterator.MoveNext())
{
if (!predicate(previous, iterator.Current))
{
yield return list;
list = new List<T>();
}
list.Add(iterator.Current);
previous = iterator.Current;
}
yield return list;
}
}
答案 1 :(得分:0)
如果您只想使用本机Linq方法执行此操作,则必须在linq查询之外保留一种状态变量。这不是好习惯,但这可行:
var groupNum = 0;
var prevDate = DateTime.MinValue;
var threshold = -TimeSpan.FromMinutes(6); // negative time makes things easier
var groups = messages.GroupBy(
m => prevDate - (prevDate = m.Date) < threshold ? ++groupNum : groupNum);
同样,不建议在Linq查询之外跟踪状态变量,这种代码非常丑陋且令人困惑。但它确实有效。
我可能会在生产环境中使用更像Servy's answer的内容。