2011-07-05 78 views
1

我怎麼能更改下面的方法來遞歸方法實現了以下方法:使用遞歸C#

public List<ScanItem> search(List<ScanItem> allItems) 
    { 
     List<ScanItem> rt = new List<ScanItem>(); 

     foreach (ScanItem s in allItems) 
     { 
      if (s.IsDirectory) 
      { 
       rt.Add(s); 



       foreach (ScanItem s1 in ((ScanDir)s).Items) 
       { 
        if (s1.IsDirectory) 
        { 
         rt.Add(s1); 




         foreach (ScanItem s2 in ((ScanDir)s1).Items) 
         { 
          if (s2.IsDirectory) 
          { 
           rt.Add(s2); 

           foreach (ScanItem s3 in ((ScanDir)s2).Items) 
           { 
            if (s3.IsDirectory) 
            { 
             rt.Add(s3); 

             /// repeat until there are no more direcotries 

            } 
            else 
             if (s3.Name.Contains("Foo")) 
              rt.Add(s3); 
           } 

          } 
          else 
           if (s2.Name.Contains("Foo")) 
            rt.Add(s2); 
         } 



        } 
        else 
         if (s1.Name.Contains("Foo")) 
          rt.Add(s1); 
       } 


      } 
      else     
       if (s.Name.Contains("Foo"))      
        rt.Add(s);      

     } 

     return rt; 

    } 

讓我告訴你我是如何構建它:

第一步:

public List<ScanItem> search(List<ScanItem> allItems) 
    { 
     List<ScanItem> rt = new List<ScanItem>(); 

     foreach (ScanItem s in allItems) 
     { 
      if (s.IsDirectory) 
      { 
       rt.Add(s); 

      } 
      else     
       if (s.Name.Contains("Foo"))      
        rt.Add(s);      

     } 

     return rt; 

    } 

Step2:

public List<ScanItem> search(List<ScanItem> allItems) 
    { 
     List<ScanItem> rt = new List<ScanItem>(); 

     foreach (ScanItem s in allItems) 
     { 
      if (s.IsDirectory) 
      { 
       rt.Add(s); 



       foreach (ScanItem s1 in ((ScanDir)s).Items) 
       { 
        if (s1.IsDirectory) 
        { 
         rt.Add(s1); 

        } 
        else 
         if (s1.Name.Contains("Foo")) 
          rt.Add(s1); 
       } 


      } 
      else     
       if (s.Name.Contains("Foo"))      
        rt.Add(s);      

     } 

     return rt; 

    } 

步驟3:

public List<ScanItem> search(List<ScanItem> allItems) 
    { 
     List<ScanItem> rt = new List<ScanItem>(); 

     foreach (ScanItem s in allItems) 
     { 
      if (s.IsDirectory) 
      { 
       rt.Add(s); 



       foreach (ScanItem s1 in ((ScanDir)s).Items) 
       { 
        if (s1.IsDirectory) 
        { 
         rt.Add(s1); 




         foreach (ScanItem s2 in ((ScanDir)s1).Items) 
         { 
          if (s2.IsDirectory) 
          { 
           rt.Add(s2); 

          } 
          else 
           if (s2.Name.Contains("Foo")) 
            rt.Add(s2); 
         } 



        } 
        else 
         if (s1.Name.Contains("Foo")) 
          rt.Add(s1); 
       } 


      } 
      else     
       if (s.Name.Contains("Foo"))      
        rt.Add(s);      

     } 

     return rt; 

    } 

第4步:

public List<ScanItem> search(List<ScanItem> allItems) 
    { 
     List<ScanItem> rt = new List<ScanItem>(); 

     foreach (ScanItem s in allItems) 
     { 
      if (s.IsDirectory) 
      { 
       rt.Add(s); 



       foreach (ScanItem s1 in ((ScanDir)s).Items) 
       { 
        if (s1.IsDirectory) 
        { 
         rt.Add(s1); 




         foreach (ScanItem s2 in ((ScanDir)s1).Items) 
         { 
          if (s2.IsDirectory) 
          { 
           rt.Add(s2); 

           foreach (ScanItem s3 in ((ScanDir)s2).Items) 
           { 
            if (s3.IsDirectory) 
            { 
             rt.Add(s3); 

            } 
            else 
             if (s3.Name.Contains("Foo")) 
              rt.Add(s3); 
           } 

          } 
          else 
           if (s2.Name.Contains("Foo")) 
            rt.Add(s2); 
         } 



        } 
        else 
         if (s1.Name.Contains("Foo")) 
          rt.Add(s1); 
       } 


      } 
      else     
       if (s.Name.Contains("Foo"))      
        rt.Add(s);      

     } 

     return rt; 

    } 

請注意,我只是不停的複製:

       foreach (ScanItem s3 in ((ScanDir)s2).Items) 
           { 
            if (s3.IsDirectory) 
            { 
             rt.Add(s3); 

             /// repeat until there are no more direcotries 

            } 
            else 
             if (s3.Name.Contains("Foo")) 
              rt.Add(s3); 
           } 

回答

3
private void SearchCore(IEnumerable<ScanItem> items, List<ScanItem> foundItems) 
{ 
    foreach (ScanItem s in items) 
    { 
     if (s.IsDirectory) 
     { 
      foundItems.Add(s); 
      searchCore (((ScanDir)s2).Items, foundItems); 
     } 
     else if (s.Name.Contains("Foo"))      
       foundItems.Add(s); 
    } 
} 

public List<ScanItem> Search(List<ScanItem> allItems) 
{ 
    List<ScanItem> foundItems = new List<ScanItem>(); 
    searchCore (allItems, foundItems); 
    return foundItems; 
} 
3
public IEnumerable<ScanItem> Search(IEnumerable<ScanItem> allItems, 
    string nameContains) 
{ 
    foreach (var item in allItems) 
    { 
     if (item.IsDirectory) 
      foreach (var child in Search(((ScanDir)item).Items, nameContains)) 
       yield return child; 
     else if (item.Name.Contains(nameContains)) 
      yield return item; 
    } 
} 
2

我安排一下,像這樣:

public IEnumerable<ScanItem> GetItems(IEnumerable<ScanItem> allItems) 
{ 
    foreach (var item in allItems) 
    { 
     if (!item.IsDirectory) 
      yield return item; 
     else 
      foreach (var child in GetItems(item.Items)) 
       yield return child; 
    } 
} 

// ... 

return GetItems(allItems).Where(i => i.Name.Contains("foo")); 
1

Linq的做法與遞歸:

public List<ScanItem> Search(List<ScanItem> scanItems) 
{ 
    List<ScanItem> results = scanItems.Where(x => x.IsDirectory) 
             .Select(x => Search(((ScanDir)x).Items)) 
             .SelectMany(s => s) 
             .ToList(); 
    results.AddRange(scanItems.Where(x => !x.IsDirectory && 
              x.Name.Contains("Foo"))); 
    return results; 
}