user2376997
user2376997

Reputation: 511

C# arbitrary nested Lists

In Python I can convert a binary tree structure to an arbitrary nested List:

    great
   /     \
  gr     eat
 / \    /   \
g   r  e    at
           /  \
          a    t

[great, [gr, [g, r], eat, [e, at, [a, t]]]

Is there a way to build an arbitrary nested List in C#?

EDIT: I took a BinaryTree<T> class from MSDN docs as a base class for my custom StrBinaryTree class. Method FormTree is doing a job for creating a tree structure from a string:

   public class StrBinaryTree : BinaryTree<string>
{
    public StrBinaryTree(string data)
    {
        if (data.Length == 0)
        {
            base.Root = null;
            base.Count = 0;
        }
        else
        {
            base.Root = new BinaryTreeNode<string>();
            base.Root.Data = data;
            base.Count = 1;
        }
    }

    public void FormTree(BinaryTreeNode<string> node)
    {
        var subLength = node.Data.Length / 2;
        if (subLength == 0)
            return;

        node.Left = new BinaryTreeNode<string>(node.Data.Substring(0, subLength));
        node.Right = new BinaryTreeNode<string>(node.Data.Substring(subLength));
        base.Count += 2;

        FormTree(node.Left);
        FormTree(node.Right);
    }
...}

Upvotes: 2

Views: 721

Answers (3)

Enigmativity
Enigmativity

Reputation: 117124

Try this:

public Tree<string> Build(string text)
{
    var tree = new Tree<string>() { Value = text };
    if (text.Length > 1)
    {
        tree.Add(Build(text.Substring(0, text.Length / 2)));
        tree.Add(Build(text.Substring(text.Length / 2)));
    }
    return tree;
}

public class Tree<T> : List<Tree<T>>
{
    public T Value;
    public override string ToString()
    {
        var r = $"\"{this.Value}\"";
        if (this.Any())
        {
            r += $" [{String.Join(", ", this.Select(t => t.ToString()))}]";
        }
        return r;
    }
}

When I run Build("great") I get:

"great" ["gr" ["g", "r"], "eat" ["e", "at" ["a", "t"]]]

Upvotes: 1

Slava Utesinov
Slava Utesinov

Reputation: 13488

Try this solution

public static List<object> Solve(string input, List<object> list = null)
{
    if (list == null)
        return Solve(input, new List<object> { input });

    if (input.Length > 1)
    {
        var middle = input.Length / 2;
        var first = input.Substring(0, middle);
        var second = input.Substring(middle);

        var innerList = new List<object>();                       
        list.Add(innerList);

        foreach (var side in new[] { first, second })
        {
            innerList.Add(side);
            Solve(side, innerList);
        }
    }

    return list;
}

public static void Show(object input)
{
    if (!(input is string))
    {
        Console.Write("[");
        var list = input as List<object>;
        foreach (var item in list)
        {
            Show(item);
            if (item != list.Last())
                Console.Write(", ");
        }
        Console.Write("]");
    }
    else
        Console.Write(input);
}

Usage:

var result = Solve("great");
Show(result);//[great, [gr, [g, r], eat, [e, at, [a, t]]]]

Approximate code for BinaryTreeNode:

public static BinaryTreeNode<string> Solve(BinaryTreeNode<string> node)
{    
    if(node.Data.Length > 1)
    {
        var middle = node.Data.Length / 2;
        var left = node.Data.Substring(0, middle);
        var right = node.Data.Substring(middle);    

        node.Left = Solve(new BinaryTreeNode<string>(left));
        node.Right = Solve(new BinaryTreeNode<string>(right));      
    }

    return node;
}

Usage:

var result = Solve(new BinaryTreeNode<string>("great"));

Upvotes: 1

s0me1
s0me1

Reputation: 109

I would use recursion to go through the tree. Since you didn't told us the type of the tree we cannot provide you c# sample code.

But it would be something like this:

void List<Object> GetNestedListFromTree(Tree tree, List<Object> list = null)
{
    List<Object> curList;

    if (!tree.HasChildNodes)
        return list;
    else
    {
        if (list==null)
        {
            list = new List<Object>;
            curList = list;
        } 
        else
        {
            curList = new List<Object>;
            list.Add(curList);
        }

        foreach(node in tree.ChildNodes)
        {
            curList.Add(node.Name);
            curList.Add(GetNestedListFromTree(node.GetSubtree, curList));
        }

        return curList;
    }
}

This isn't tested because I don't know your tree but yeah ... It should work if your tree can provide the needed functionality.

Upvotes: 2

Related Questions