Search code examples
c#dictionarydata-structuresnesteddirectory-structure

store parent, child, grand- child data in memory


I'm looking for the simplest method to store parent child data in memory for manipulation. There will be approx 100 parents, 20 children and 30 grand-children and only the number of parents will change, all child and grand-child properties will be known before compiling. I would like to access the grand children data using the parent ID and property name as a key. I could use a simple class with 200 odd properties, but I'm sure there's a more efficient method.

I've come across nested dictionaries/classes/structures/tuples, lists of lists, lists of arrays, json, non-binary trees etc but most posts are several years old and I'm not sure which method is best.

Please can anyone suggest which method to use or if there's a good library available?

    ID (1 to 100)
        |
        param 1   param 2   param 3  param 4.....param 20
        -val 1    -val 1   -val 1    -val 1      -val 1
        -val 2    -val 2   -val 2    -val 2      -val 2
        -val 3    -val 3   -val 3    -val 3      -val 3
        ...
        -val 30    -val 30   -val 30    -val 30      -val 30

Solution

  • I'd start with a simple, standard approach: define a class for a tree structure and use a list collection for the children nodes and a convenient contructor to assign a parent.

     public class Node
     {
         public List<Node> children = new List<Node>();
    
         public string Name;
         public int? Val;
    
         public Node Parent = null;
    
         public Node(string name, int? val, Node fromParent = null) {
             Name = name;
             Val = val;
             if (fromParent != null)
             {
                 Parent = fromParent;
                 fromParent.children.Add(this);
             }
         }
    
     }
    

    A trivial usage:

    var parent1 = new Node("parent1",10);
    var child1 = new Node("child", 30, parent1);
    

    Inheritance example

    Subclasses

    public class Root : Node
    {
        public int ParentID;
        public Root(int id) : base(null, null, null)
        {
            ParentID = id;
        }
    }
    
    public class Parameter : Node
    {
        public string ParameterType;
        public Parameter(string paramName, string paramType, Node fromParent = null) : base(paramName, null, fromParent)
        {
            ParameterType = paramType;
        }
    }
    public class Value : Node
    {
        public string Unit;
        public Value(int val, string unit, Node fromParent = null) : base(null, val, fromParent)
        {
            Unit = unit;
        }
    }
    

    and how to instantiate them (with random values)

    List<Node> parents = new List<Node>();
    Random rnd = new Random();
    for (int k = 0; k < 100; k++)
    {
        var parentk = new Root(k);
        for (int kk = 0; kk < 20; kk++)
        {
            var paramkk = new Parameter("simple" + kk, "param1", parentk);
            for (int kkk = 0; kkk < 30; kkk++)
            {
                int dice = rnd.Next(1, 1000000);
                var valkkk = new Value(dice, "bar", paramkk);
            }
    
        }
        parents.Add(parentk);
    }
    

    in-memory searches

    Let's say you have the above collection of parents and you want to find the one with max value for param1

    DateTime start = DateTime.Now;
    var mySearch = parents.SelectMany(x => x.children)
        .Where(x => ((Parameter)x).ParameterType == "param1")
      .GroupBy(x => x.Parent,
        x => x.children,
        (key, gr) =>
        new
        {
            Key = key,
            MaxVal = gr.Max(y => y.Max(z => z.Val))
        }).OrderByDescending(x => x.MaxVal).First();
    var foundID = ((Root)mySearch.Key).ParentID;
    DateTime stop  = DateTime.Now;
    
    var elapsed = (stop - start).TotalMilliseconds;
    

    and this search took about 15 milliseconds on my laptop