Skip to content

Instantly share code, notes, and snippets.

@marbel82
Last active June 30, 2020 07:54
Show Gist options
  • Save marbel82/3fcfb81d6ff35960186eb1f85debdd83 to your computer and use it in GitHub Desktop.
Save marbel82/3fcfb81d6ff35960186eb1f85debdd83 to your computer and use it in GitHub Desktop.
How to unroll a recursive structure and return as IEnumerable

TODO: solution using Stack

stackoverflow questions:

How to “unroll” a “recursive” structure

IEnumerable and Recursion using yield return

My considerations

Same function in two versions. The function goes through all the elements recursively and return they as IEnumerable.

There is no solution yet, using Stack

public class ResourceFileInfo
{
    ...
    // By yield  
    public IEnumerable<ResourceInfo> GetAllResources1()
    {
        if (_localResources != null)
        {
            foreach (ResourceInfo ri in _localResources)
            {
                yield return ri;
            }
        }

        if (_mergedFiles != null)
        {
            foreach (ResourceFileInfo file in _mergedFiles)
            {
                foreach (ResourceInfo fri in file.Resources)
                {
                    yield return fri;
                }
            }
        }
    }
    
    // By Concat & SelectMany
    public IEnumerable<ResourceInfo> GetAllResources2
    {
        if (_localResources != null)
        {
            if (_mergedFiles != null)
                return _localResources.Concat(_mergedFiles.SelectMany(x => x.Resources));
            else
                return _localResources;
        }
        else
        {
            if (_mergedFiles != null)
                return _mergedFiles.SelectMany(x => x.Resources);
            else
                return Enumerable.Empty<ResourceInfo>();
        }
    }
}

Object structure:

  • 📁 ResourceFileInfo
    • 📁 ResourceFileInfo
      • 📦 ResourceInfo
      • 📦 ResourceInfo
    • 📁 ResourceFileInfo
      • 📁 ResourceFileInfo
        • 📦 ResourceInfo
      • 📦 ResourceInfo
    • 📦 ResourceInfo
public class ResourceInfo
{
    public string ClassName { get; }
    public string XKey { get; }

    public ResourceInfo(string className, string xKey)
    {
        ClassName = className;  
        XKey = xKey;
    }
}
public class ResourceFileInfo
{
    internal ResourceFileInfo[] _mergedFiles;
    internal ResourceInfo[] _localResources;

    public string Path { get; }

    public IEnumerable<ResourceFileInfo> MergedFiles
        => _mergedFiles ?? Enumerable.Empty<ResourceFileInfo>();

    public IEnumerable<ResourceInfo> LocalResources
        => _localResources ?? Enumerable.Empty<ResourceInfo>();

    public ResourceFileInfo(AssemblyInfo parentAssembly, string path)
    {
        ParentAssembly = parentAssembly;
        Path = path;
    } 
    ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment