Feedback

LINQ: Hierarchie flach machen

Sprache: C#

Diese kleine Erweiterungsmethode dient zum "flach machen" einer hierarchische Objekt-Struktur. Angenommen man hat in Windows Forms eine TreeView und möchte sämtliche Items in eine ListBox übertragen. Dann geht das mit meiner Methode in nur einer Zeile: [code]this.listBox1.Items.Clear(); this.listBox1.Items.AddRange( this.treeView1.Nodes .Cast<TreeNode>() .SelectMany(x => x.Flatten(y => y.Nodes.Cast<TreeNode>())) .Select(x => (object)x.Text) .ToArray());[/code] Sofern man generische Listen nutzt kann man sich den Cast auch sparen, hier allerdings wird er benötigt. [b]Benötigte Namespaces[/b] System System.Collections.Generic System.Linq
/// <summary>
/// Verflacht eine hierarchische Objekt-Struktur.
/// </summary>
/// <typeparam name="T">Der Typ der Elemente in der Hierachie</typeparam>
/// <param name="item">Das Root-Objekt dessen Sub-Elemente verflacht werden sollen. Dieses wird als erstes in die Rückgabeliste gegeben.</param>
/// <param name="selector">Eine Funktion zum Auswählen der Unter-Elemente unter einem Element.</param>
/// <returns>Eine Auflistung aller Elemente unter <paramref name="item"/> inklusive <paramref name="item"/> selbst</returns>
public static IEnumerable<T> Flatten<T>(this T item, Func<T, IEnumerable<T>> selector)
{
    yield return item;
    foreach (var subSubItem in selector(item).SelectMany(subItem => Flatten(subItem, selector)))
    {
        yield return subSubItem;
    }
}
/// <summary>
/// Verflacht eine hierarchische Objekt-Struktur.
/// </summary>
/// <typeparam name="T">Der Typ der Elemente in der Hierachie</typeparam>
/// <param name="item">Das Root-Objekt dessen Sub-Elemente verflacht werden sollen. Dieses wird als erstes in die Rückgabeliste gegeben.</param>
/// <param name="selector">Eine Funktion zum Auswählen der Unter-Elemente unter einem Element.</param>
/// <returns>Eine Auflistung aller Elemente unter <paramref name="item"/> inklusive <paramref name="item"/> selbst</returns>
public static IEnumerable<T> Flatten<T>(this T item, Func<T, IEnumerable<T>> selector)
{
    yield return item;
    foreach (var subSubItem in selector(item).SelectMany(subItem => Flatten(subItem, selector)))
    {
        yield return subSubItem;
    }
}