views:

69

answers:

2

Hello all , I'm new to c# and I'd like to make a method to generate a hierarchy ID like the following

1.0
 1.1
   1.1.1
   1.1.2
   1.1.3

 1.2
 1.3
2.0
 2.1

is there and way to accomplish this ? any help will be highly appreciated.

+2  A: 

Here is my quick attempt.

I am assuming that instead of 1.0 and 2.0 you meant just 1 and 2, respectively, as otherwise it would be inconsistent.

public class HierarchyGenerator
{
    private List<int> levels = new List<int> { 1 };

    public void DownOneLevel()
    {
        levels.Add(1);
    }

    public void UpLevels(int numLevels)
    {
        if (levels.Count < numLevels + 1)
            throw new InvalidOperationException(
                "Attempt to ascend beyond the top level.");

        for (int i = 0; i < numLevels; i++)
            levels.RemoveAt(levels.Count - 1);
        MoveNext();
    }

    public void MoveNext()
    {
        levels[levels.Count - 1]++;
    }

    public string Current
    {
        get
        {
            return new string(' ', (levels.Count - 1) * 2)
                 + string.Join(".", levels.Select(l => l.ToString()));
        }
    }
}

static partial class Program
{
    static void Main()
    {
        var hg = new HierarchyGenerator();
        Console.WriteLine(hg.Current);  // 1
        hg.DownOneLevel();
        Console.WriteLine(hg.Current);  // 1.1
        hg.DownOneLevel();
        Console.WriteLine(hg.Current);  // 1.1.1
        hg.MoveNext();
        Console.WriteLine(hg.Current);  // 1.1.2
        hg.MoveNext();
        Console.WriteLine(hg.Current);  // 1.1.3
        hg.UpLevels(1);
        Console.WriteLine(hg.Current);  // 1.2
        hg.MoveNext();
        Console.WriteLine(hg.Current);  // 1.3
        hg.UpLevels(1);
        Console.WriteLine(hg.Current);  // 2
        hg.DownOneLevel();
        Console.WriteLine(hg.Current);  // 2.1
    }
}
Timwi
Thanks Timwi, this is exactly what i need
Cracker
+2  A: 

I'll assume that your hierarchy is expressed like a tree using this class:

class Node {
  public Node() { Children = new Node[0]; }
  public String Name { get; set; }
  public IEnumerable<Node> Children { get; set; }
}

You can then visit each node in the tree using this method:

void Visit(Node node, Stack<Int32> levels, Action<Node, String> nodeAction) {
  // Generation of hierachyId can be customized here to say use letters.
  var hierarchyId = 
    String.Join(".", levels.Reverse().Select(l => l.ToString()).ToArray());
  nodeAction(node, hierarchyId);
  var i = 1;
  foreach (var child in node.Children) {
    levels.Push(i++);
    Visit(child, levels, nodeAction);
    levels.Pop();
  }
}

This code will visit each node in the tree in a depth first order including the root. However, the root will have an empty hierarchyId. To start visiting the tree use this code:

Visit(
  root,
  new Stack<int>(),
  (node, hierarchyId) => Console.WriteLine(hierarchyId + ": " + node.Name)
);

The action will simply write the node name and generated hierarchy id to the console.

Here are some sample data:

var root = new Node {
  Name = "Root",
  Children = new[] {
    new Node {
      Name = "A",
      Children = new[] {
        new Node {
          Name = "AA",
          Children = new [] {
            new Node { Name = "AAA" },
            new Node { Name = "AAB" },
            new Node { Name = "AAC" }
          }
        },
        new Node { Name = "AB" },
        new Node { Name = "AC" }
      }
    },
    new Node {
      Name = "B",
      Children = new Node[] {
        new Node { Name = "BA" }
      }
    }
  }
};

Running the code on this tree writes the following to the console:

: Root
1: A
1.1: AA
1.1.1: AAA
1.1.2: AAB
1.1.3: AAC
1.2: AB
1.3: AC
2: B
2.1: BA
Martin Liversage