title: Search Hierarchical List Recursively
body: <p>I have a hierarchical list of objects.  Assume that the structure is as follows:</p>
  
  <ul>
  <li>Root node
  <ul>
  <li>Parent node
  <ul>
  <li>child node</li>
  </ul></li>
  <li>Parent node
  <ul>
  <li>child node</li>
  </ul></li>
  <li>Parent node
  <ul>
  <li>child node</li>
  </ul></li>
  </ul></li>
  </ul>
  
  <p>The child nodes could have their own children, but the objective is to basically search the "parent nodes".  So, let's say that the parent node class has a property called "Name" - and the user enters a partial name, I want all of the parent nodes whose name contains the user's search criteria to be returned.  Basically, this is more of a "filter" functionality than anything.  So, I know how to do this, however, the problem that I am running into is that they key objective is to keep the hierarchical structure in tact.  In other words, if there is one parent node that matches the filter criteria, I want the structure below to be returned:</p>
  
  <ul>
  <li>Root node
  <ul>
  <li>Parent node
  <ul>
  <li>child node</li>
  </ul></li>
  </ul></li>
  </ul>
  
  <p>My current efforts only yield:</p>
  
  <ul>
  <li>Parent node
  <ul>
  <li>child node</li>
  </ul></li>
  </ul>
  
  <p>I am using Linq.  Any suggestions would be greatly appreciated.</p>
  
  <p>Thanks!</p>
  
  <p>Chris</p>
  
  <p>Code snippet below for current filter implementation:</p>
  
  <pre><code>FilteredReports = Reports.FirstOrDefault().Children.Cast&lt;IHierarchicalResult&gt;()
                                      .SelectRecursive(item =&gt; item.Children.Cast&lt;IHierarchicalResult&gt;())
                                      .Where(item =&gt; item.Name.ToLower().StartsWith(filterCriteria))
                                      .ToObservableCollection();
  </code></pre>
  
  <p>Here is the extension method I am using:</p>
  
  <pre><code>public static IEnumerable&lt;T&gt; SelectRecursive&lt;T&gt;(this IEnumerable&lt;T&gt; source, Func&lt;T, IEnumerable&lt;T&gt;&gt; getChildren)
      {
          if (null == source)
          {
              throw new ArgumentNullException("source");
          }
  
          if (null == getChildren) return source;
  
          return SelectRecursiveIterator(source, getChildren);
      }
  
      private static IEnumerable&lt;T&gt; SelectRecursiveIterator&lt;T&gt;(IEnumerable&lt;T&gt; source, Func&lt;T, IEnumerable&lt;T&gt;&gt; getChildren)
      {
          foreach (T item in source)
          {
              yield return item;
  
              IEnumerable&lt;T&gt; children = getChildren(item);
              if (null != children)
              {
                  foreach (T child in SelectRecursiveIterator(children, getChildren))
                  {
                      yield return child;
                  }
              }
          }
      }
  </code></pre>