Удалить выбранный узел в иерархии с рекурсией и обобщениями - PullRequest
0 голосов
/ 13 февраля 2012

Я хочу сгладить иерархию объектов с открытым Generic T.

Эта ссылка Рекурсивное выравнивание списка

показывает, как это сделать, принимая переданныйIEnumerable.Но я хочу сгладить переданный объект T и

его свойство Children универсальным и рекурсивным способом.

U1.Children(U2,U3,U4)
U2.Children(U9,U10)
U3.Children(U11,U12)
U4.Children(U20,U30)

Я перехожу к методу U1 (выбранный узел) и хочучтобы получить этот плоский список:

U1,U2,U3,U4,U9,U10,U11,U12,U20,U30

Возможно ли это как-то универсальным образом?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Вы можете определить рекурсивный метод расширения, который принимает функцию для извлечения потомков:

public static IEnumerable<T> Flatten<T>(this T root, Func<T, IEnumerable<T>> getChildren)
{
    IEnumerable<T> rootSingleton = new T[] { root };
    IEnumerable<T> children = getChildren(root);
    IEnumerable<T> descendants = children.SelectMany(child => Flatten(child, getChildren));
    return rootSingleton.Concat(descendants);
}

Тогда вы можете потреблять его так:

var flat = u1.Flatten(u => u.Children);
0 голосов
/ 14 февраля 2012

если ваша иерархия имеет только одну глубину уровня, вы можете использовать select many с union

public IEnumerable<T> Flattern<T>(IEnumerable<T> input) where T : ISomeinterface {
    return input.SelectMany(t=> t.Children).Union(input)
}

Что ж, этот код не будет компилироваться, если вы не ограничите его базовым классом или интерфейсом с Children имущество.Компилятор должен знать, что объект имеет это свойство l

...