2

我需要使用自定义条件对数据进行分组,该条件返回trueor 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)也必须在分组中,但要单独进行(每组一个)。

但我认为这是一个有点肮脏的解决方案,所以我认为也许有更优雅的东西?

4

2 回答 2

3

我认为您的解决方案有效;我肯定会添加详细的评论来解释预期的结果。

如果您想使用“内置”字符串生成器而不是创建自己的字符串生成器,您可以使用Guid.NewGuid()

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

此外,除非您想稍后使用该值,否则您不需要匿名类型:Condition

var result = data.GroupBy(d => d.SomeValue > 1 
                               ? Guid.Empty 
                               : Guid.NewGuid() )
于 2013-08-22T12:39:43.920 回答
0

最简单的方法是这样的:

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