最も簡単な方法は次のようなものです。
var result = data
.GroupBy(d => d.SomeValue > 1 ? 0 : d.ID);
仮定ID
は、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の回答Guid
が唯一の方法かもしれませんが、単純な Linq クエリの場合、これは、グループ化されていないすべてのアイテムに対してランダムを生成するよりも効率的です。
もちろん、これが洗練されていないと思われる場合は、いつでも拡張メソッドでラップできます。いずれにせよ、キーはここでは実際には関係ないため、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);