Как добиться следующего с помощью LINQ множественного GroupBy - PullRequest
0 голосов
/ 10 декабря 2018

Я использую следующие две функции для достижения динамического вложенного 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); }

}

Пример некоторых элементов, сгруппированных этимпуть ниже:

Мир
Европа
Франция
Камера (включая HD с дистанционным управлениемдвижение активировано)
Франция
Камера (вкл. HD с дистанционным управлением активирована)
Испания
Патрульная машина

Я хотел бы добиться следующего:

World
Европа
Франция
Камера(вкл. HD с дистанционным управлением, активированное движение)
Камера (вкл. HD с дистанционным управлением, активированное движение)
Испания
Патрульная машина

In полужирный есть свойство Key класса GroupResult.

Есть идеи, как добиться этого соединения по ключу на самом низком уровне?

...