Search code examples
c#recursionneo4jclient

Recursively Adding tree structure to a List C#


So I have some code that performs a Neo4j cypher query that returns an IEnumerable of type FolderObject like so:

public IEnumerable<FolderObject> GetChild(string parentId)
{
    IEnumerable<FolderObject> childNode = null;
    var query = GraphConnection.Cypher
    .Start(new { n = Node.ByIndexLookup("node_auto_index", "ObjectId", parentId) })
    .Match("(n)-[r:HAS_FOLDER]->(b)")
    .Where("b.ParentId = n.ObjectId")
    .Return<FolderObject>("b");

    childNode = query.Results;

    return childNode;
}

FolderObject looks like so:

public string ObjectId { get; set; }
public string ParentId {get; set;}
public List<GraphObject> Children { get; set; }

Then I have this method which works fine:

public List<FolderObject> GetChildren(string repositoryId, string folderId)
{
    List<FolderObject> items;

    QueryOperations query = new QueryOperations(GraphConnection);

    var queryResult = query.GetChild(folderId);

    string childId = null;

    if (queryResult != null)
    {
        foreach (var item in queryResult)
        {
            childId = item.ObjectId;

            items = new List<FolderObject>();

            items.Add(item);

            var nextChild = GetChildren(repositoryId, childId);
        }
    }
    else
    {
        throw new Exception("The Folder with Id: " + folder + " could not be found.");
    }

    return items
}

Now the problem comes when I try and do this recursively. What I need to do is get the top most folder add that to a list then get the next folder below the top most and add that in as a child. Then repeat until there are no more children.

The structure as follows:

-Folder
    -Folder
        -Folder
            -Folder

and return this structure as a List?

Here is the Json

{
    "ParentId": "0",
    "ObjectId": "1",
    "children": [
        {
            "ParentId": "1",
            "ObjectId": "2",
            "children": [
                {
                    "ParentId": "2",
                    "ObjectId": "3"
                }
            ]
        }
    ]
}

Solution

  • You could use a Stack<FolderObject> which is similar to a recursive method, the only difference is that it's not recursive. Imho it's more readable and less complex.

    public List<FolderObject> GetChildren(string repositoryId, string folderId)
    {
        List<FolderObject> items = new List<FolderObject>();;
    
        QueryOperations query = new QueryOperations(GraphConnection);
        var queryResult = query.GetChild(folderId);
    
        Stack<FolderObject> folders = new Stack<FolderObject>(queryResult);
    
        while (folders.Count > 0)
        {
            FolderObject currentFolder = folders.Pop();
            var childId = currentFolder.ObjectId;
            items.Add(currentFolder);
            var nextChildren = GetChildren(repositoryId, childId);
            foreach (FolderObject child in nextChildren)
                folders.Push(child);
        }
    
        return items;
    }