Рекурсивное выравнивание списков - PullRequest
33 голосов
/ 26 сентября 2008

Я, вероятно, мог бы написать это сам, но конкретный способ, которым я пытаюсь добиться этого, сбивает меня с толку. Я пытаюсь написать общий метод расширения, похожий на другие, представленные в .NET 3.5, который возьмет вложенный IEnumerable из IEnumerables (и т. Д.) И сведет его в один IEnumerable. У кого-нибудь есть идеи?

В частности, у меня проблемы с синтаксисом самого метода расширения, чтобы я мог работать над алгоритмом выравнивания.

Ответы [ 13 ]

0 голосов
/ 03 мая 2018
class PageViewModel { 
    public IEnumerable<PageViewModel> ChildrenPages { get; set; } 
}

Func<IEnumerable<PageViewModel>, IEnumerable<PageViewModel>> concatAll = null;
concatAll = list => list.SelectMany(l => l.ChildrenPages.Any() ? 
    concatAll(l.ChildrenPages).Union(new[] { l }) : new[] { l });

var allPages = concatAll(source).ToArray();
0 голосов
/ 26 сентября 2008

Как правило, вам нужно иметь главный IENumerable, который находится вне вашей рекурсивной функции, а затем в вашей рекурсивной функции (псевдо-код)

private void flattenList(IEnumerable<T> list)
{
    foreach (T item in list)
    {
        masterList.Add(item);

        if (item.Count > 0)
        {
            this.flattenList(item);
        }
    }
}

Хотя я действительно не уверен, что вы подразумеваете под IEnumerable, вложенным в IEnumerable ... что внутри этого? Сколько уровней вложенности? Какой окончательный тип? очевидно, мой код неверен, но я надеюсь, что это заставит вас задуматься.

0 голосов
/ 26 сентября 2008
static class EnumerableExtensions
{
    public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> sequence)
    {
        foreach(var child in sequence)
            foreach(var item in child)
                yield return item;
    }
}

Может быть, так? Или вы имеете в виду, что он потенциально может быть очень глубоким?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...