2

trueまたはを返すカスタム条件を使用してデータをグループ化する必要がありますfalse。複雑なのは、返されるアイテムのみをtrueグループ化し、他のアイテムをグループ化する必要がないことです。

私が使用する場合:

var result = data.GroupBy(d => new { Condition = d.SomeValue > 1 });

すべてのアイテムはtrue/でグループ化されfalseます。

今、私は機能するこのステートメントを持っています:

var result = data.GroupBy(d => new { Condition = d.SomeValue > 1 ? "true" : FunctionToGetUniqueString() });

更新:他の項目 ( false) もグループ化する必要がありますが、個別に (グループごとに 1 つ) 移動することに注意してください。

しかし、それは少し汚い解決策だと思うので、もっとエレガントなものがあるのではないかと思いますか?

4

2 に答える 2

0

最も簡単な方法は次のようなものです。

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);
于 2013-08-22T12:35:30.390 に答える