使用递归c#实现以下方法

时间:2011-07-05 18:31:26

标签: c# recursion

如何将以下方法更改为递归方法:

    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);
                                }

4 个答案:

答案 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;
}