如何将以下方法更改为递归方法:
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;
}
让我告诉你我是如何构建的:
步骤1:
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;
}
步骤2:
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);
}
答案 0 :(得分: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;
}
}
答案 1 :(得分: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;
}
答案 2 :(得分: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"));
答案 3 :(得分: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;
}