Jak „rozwinąć” strukturę „rekurencyjną”
Nie wiem, jak to nazwać, ale powiedz, że masz klasę, która wygląda tak:
class Person
{
public string Name;
public IEnumerable<Person> Friends;
}
Następnie masz osobę i chcesz „rozwinąć” tę strukturę rekurencyjnie, dzięki czemu otrzymasz jedną listę wszystkich osób bez duplikatów.
Jak byś to zrobił? Zrobiłem już coś, co wydaje się działać, ale jestem ciekawy, jak inni by to zrobili, a zwłaszcza jeśli w Linq jest coś wbudowanego, którego można użyć w sprytny sposób, aby rozwiązać ten mały problem :)
Oto moje rozwiązanie:
public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> subjects, Func<T, IEnumerable<T>> selector)
{
// Stop if subjects are null or empty
if(subjects == null)
yield break;
// For each subject
foreach(var subject in subjects)
{
// Yield it
yield return subject;
// Then yield all its decendants
foreach (var decendant in SelectRecursive(selector(subject), selector))
yield return decendant;
}
}
Byłoby użyte coś takiego:
var people = somePerson.SelectRecursive(x => x.Friends);