最简单的方法是这样的:
var result = data
.GroupBy(d => d.SomeValue > 1 ? 0 : d.ID);
AssumingID
是一个int
在您的集合中的项目中唯一的属性。如果你有一个唯一的字符串属性等,当然可以很容易地适应这种技术。如果你没有唯一的属性,你总是可以做这样的事情:
var result = data
.Select((d, i) => new { d, i })
.GroupBy(x => x.d.SomeValue > 1 ? -1 : x.i, x => x.d);
这将适用于 Linq-to-Objects,但我不确定其他 Linq 提供程序(例如 Linq-to-SQL、Linq-to-Entities)。对于这些情况,D Stanley的答案可能是唯一的方法,但对于简单的 Linq 查询,这将比Guid
为每个非分组项目生成随机数更有效。
当然,如果这看起来不优雅,您总是可以将其包装在扩展方法中。请注意,我返回一个IEnumerable<IEnumerable<T>>
而不是IEnumerable<IGrouping<TKey, T>>
,因为无论如何关键在这里都无关紧要:
public static IEnumerable<IEnumerable<T>> GroupWhere<T>(
this IEnumerable<T> set,
Func<T, bool> grouping)
{
return set
.Select((d, i) => new { d, i })
.GroupBy(x => grouping(x.d) ? -1 : x.i, x => x.d);
}
或者这个,它的语义略有不同(分组的项目总是最后出现)但应该更有效:
public static IEnumerable<IEnumerable<T>> GroupWhere<T>(
this IEnumerable<T> set,
Func<T, bool> grouping)
{
List<T> list = new List<T>();
foreach(var x in set)
{
if (!grouping(x))
{
yield return new[] { x };
}
else
{
list.Add(x);
}
}
yield return list;
}
无论哪种方式,您都可以像这样使用它:
var result = data.GroupWhere(d => d.SomeValue > 1);