首页 > 解决方案 > 如何使用 LINQ 多个 GroupBy 实现以下目标

问题描述

我正在使用以下两个函数来实现动态嵌套 GroupBy:

    public static IEnumerable<GroupResult<TElement>> GroupByMany<TElement>(this IEnumerable<TElement> elements, params string[] groupSelectors)
    {

        var selectors =
            new List<Func<TElement, object>>(groupSelectors.Length);

        foreach (var selector in groupSelectors)
        {
            LambdaExpression l = dyn.DynamicExpression.ParseLambda(typeof(TElement), typeof(object), selector);
            selectors.Add((Func<TElement, object>)l.Compile());
        }

        return elements.GroupByMany(selectors.ToArray());

    }

    public static IEnumerable<GroupResult<TElement>> GroupByMany<TElement>(this IEnumerable<TElement> elements, params Func<TElement, object>[] groupSelectors)
    {
        if (elements.Count() > 0 && groupSelectors.Length > 0)
        {
            var selector = groupSelectors.First();

            //reduce the list recursively until zero

            var nextSelectors = groupSelectors.Skip(1).ToArray();

            return
                elements.GroupBy(selector).Select(
                    g => new GroupResult<TElement>
                    {
                        Key = g.Key ?? "(none)",
                        Count = g.Count(),
                        Items = g,
                        SubGroups = g.GroupByMany(nextSelectors)
                    });
        }
        else
            return null;
    }

这会生成 GroupResult 类型的嵌套结构:

public class GroupResult<T>

{
    public object Key { get; set; }

    public int Count { get; set; }

    public IEnumerable<T> Items { get; set; }

    public IEnumerable<GroupResult<T>> SubGroups { get; set; }

    public override string ToString()

    { return string.Format("{0} ({1})", Key, Count); }

}

以这种方式分组的一些项目的示例如下:

世界
  欧洲
    法国
      摄像机(包括高清遥控动作激活)
    法国
      摄像机(包括高清遥控动作激活)
   西班牙
     巡逻车

我想要达到的目标如下:

世界
  欧洲
    法国
      摄像头(包括高清遥控动作激活)
      摄像头(包括高清遥控动作激活)
   西班牙
     巡逻车

粗体表示GroupResult类的 Key 属性。

任何想法如何通过 Key 在最低级别实现此连接?

标签: c#linqdynamicgrouping

解决方案


推荐阅读