2

I'm searching for a construct in c# where Dictionaries contain Dictionaries to count n. I want to put a list of Dictionaries into and it builds some kind of index.

I want to call it like dic[key][key2][key3] where the value is object or a Dictionary or a Dictionary containing more Dictionaries.

I think elastic can provide something like that but our solution is a standalone client application.

Mohammed Sajid
  • 4,778
  • 2
  • 15
  • 20
Felix Arnold
  • 839
  • 7
  • 35
  • `Dictionaries contain Dictionaries to count n` -- I'm not sure what you mean there. – Blindy Feb 26 '20 at 17:03
  • You can easily create nested dictonaries, but if you don't know the nesting level or it isn't fixed, a generic (type safe) `Dictionary` may not be your best choice. For example, `Dictionary>>`. – NetMage Feb 26 '20 at 17:09
  • @NetMage I thougth about that but yes I don't know the recursion level. May be MyDictionary : Dictionary but where to stop? – Felix Arnold Feb 26 '20 at 17:12
  • 4
    Instead of trying to fit your data into predetermined structure you will be better off describing your data and [determining which data structure fits it](https://meta.stackexchange.com/questions/66377/). – Dour High Arch Feb 26 '20 at 17:20
  • 2
    could an alternative solution be using a regular, _flat_ `Dictionary`? that way, you can still quite easily navigate from `["key","key2"]` to `["key","key2","key3"]` (alternatively: concatting the strings with a separator character) – Franz Gleichmann Feb 26 '20 at 17:20

1 Answers1

2

Dictionaries can be nested like this:

        var dictionary = new Dictionary<string, Dictionary<string, int>>();

To initialise a nested dictionary:

        var dictionary = new Dictionary<string, Dictionary<string, int>>
        {
            { "a1", new Dictionary<string, int> { { "b1a", 1 }, { "b1b", 2 } } },
            { "a2", new Dictionary<string, int> { { "b2a", 3 }, { "b2b", 4 } } }
        };

You then index into the dictionary like this:

        int x = dictionary["a1"]["b1a"];
        Assert.AreEqual(1, x);

EDIT: to have an arbitrary depth, you need to create your own type that has built-in nesting, e.g.,

    class Node
    {
        public int Value { get; set; }

        public Dictionary<string, Node> Children { get; set; }

        // The indexer indexes into the child dictionary.
        public Node this[string key] => Children[key];
    }

Normally I would define Children as a List, but you want dictionaries.

Sample usage:

        var node = new Node
        {
            Children = new Dictionary<string, Node>
            {
                { "a1", new Node
                    {
                        Children = new Dictionary<string, Node>
                        {
                            { "b1a", new Node { Value = 1 } },
                            { "b1b", new Node { Value = 2 } }
                        }
                    }
                },
                { "a2", new Node
                    {
                        Children = new Dictionary<string, Node>
                        {
                            { "b2a", new Node { Value = 3 } },
                            { "b2b", new Node { Value = 4 } }
                        }
                    }
                }
            }
        };

        int y = node["a1"]["b1a"].Value;
        Assert.AreEqual(1, y);

This can go as deep as you like--just stick another Dictionary into the Children property of a leaf node.

Polyfun
  • 9,479
  • 4
  • 31
  • 39