Laden...

Linq: Flache Liste von allen nodes erstellen

Erstellt von CatWoman vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.187 Views
C
CatWoman Themenstarter:in
1 Beiträge seit 2014
vor 10 Jahren
Linq: Flache Liste von allen nodes erstellen

Hallo liebes Forum,

Ich hab mir mit den Extended Methoden von LINQ mehre abfragen erzeugt um mir eine flache Liste von allen nodes eines bestimmten node erzeugt, es funktioniert, ist aber nicht sehr elegant und auch nicht performant.

Ich benutze mehrere where, select auf cildnodes und aggregates, um die einzelnen childnodes mit union zusammenzubringen, zum schluss dann eine union um alles nodes ohne childnodes mit den untergeordneten nodes die jetzt flach sind zusammen zu bringen.

Ich will gerne noch besser werden und dazu lernen, wie es besser gemacht wird.

var result =
                childNodesFromDeviceNode.Where(
                    childNodFromDeviceNode =>
                        (childNodFromDeviceNode.HasChildNodes))
                    .Select(item => item.ChildNodes.Cast<XmlNode>())
                    .Aggregate((itemCurrent, itemNext) => itemNext.Union(itemCurrent));

            result =
                result.Union(
                    result.Where(item => item.HasChildNodes)
                        .Select(item => item.ChildNodes.Cast<XmlNode>())
                        .Aggregate((itemCurent, itemNext) => itemNext.Union(itemCurent)));

            return result.Union(childNodesFromDeviceNode).Where(item => !item.HasChildNodes);

Danke euch 😃

T
415 Beiträge seit 2007
vor 10 Jahren

Wenn es damit Performance Probleme gibt, hast das Ganze mal gegen einen ganz klassischen rekursiven Ansatz getestet? Ohne großartig auf Linq zu setzen?

656 Beiträge seit 2008
vor 10 Jahren

Hilft dir eventuell SelectMany?

4.221 Beiträge seit 2005
vor 10 Jahren

Wenn es damit Performance Probleme gibt, hast das Ganze mal gegen einen ganz klassischen rekursiven Ansatz getestet? Ohne großartig auf Linq zu setzen?

z.B: So: Rekursiver TreeView Save/Restore aufgrund des FullPaths

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

P
5 Beiträge seit 2013
vor 10 Jahren

Ich hätte folgenden rekursiven Ansatz (als Extension Method):


public static class EnumerableExtension
{
  public static IEnumerable<T> Descendants<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> descendBy)
  {
    if (!source.Any())
    {
      yield break;
    }

    foreach (T value in source)
    {
      yield return value;

      foreach (T child in descendBy(value).Descendants(descendBy))
      {
        yield return child;
      }
    }
  }
}

//Anwendung
foreach(var node in rootNode.Descendants(n => n.Children))
{
    ...
}