/// <summary>
        /// Creates a nested dictionary from an ienumerable according to a specified key selectors function, comparers, and an element selector function.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <typeparam name="TKey1">The type of the key returned by key1Selector for level 1.</typeparam>
        /// <typeparam name="TKey2">The type of the key returned by key2Selector for level 2.</typeparam>
        /// <typeparam name="TElement">The type of the value returned by elementSelector.</typeparam>
        /// <param name="source">An ienumerable to create a nested dictionary from.</param>
        /// <param name="key1Selector">A function to extract a key for level 1 from each element.</param>
        /// <param name="key2Selector">A function to extract a key for level 2 from each element.</param>
        /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
        /// <param name="comparer1">An comparer to compare keys on level 1.</param>
        /// <param name="comparer2">An comparer to compare keys on level 2.</param>
        /// <returns>A nested dictionary that contains values of type TElement selected from the input sequence.</returns>
        /// <exception cref="ArgumentNullException">source or some of keySelectors or elementSelector is null.-or- some of keySelectors produces a key that is null.</exception>
        /// <exception cref="ArgumentException">Some of keySelectors produces duplicate keys for two elements.</exception>
        public static NestedDictionary <TKey1, TKey2, TElement> ToNestedDictionary <TSource, TKey1, TKey2, TElement>(this IEnumerable <TSource> source, Func <TSource, TKey1> key1Selector, Func <TSource, TKey2> key2Selector, Func <TSource, TElement> elementSelector, IEqualityComparer <TKey1> comparer1, IEqualityComparer <TKey2> comparer2)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (key1Selector == null)
            {
                throw new ArgumentNullException(nameof(key1Selector));
            }
            if (key2Selector == null)
            {
                throw new ArgumentNullException(nameof(key2Selector));
            }
            if (elementSelector == null)
            {
                throw new ArgumentNullException(nameof(elementSelector));
            }

            NestedDictionary <TKey1, TKey2, TElement> dictionary = new NestedDictionary <TKey1, TKey2, TElement>(comparer1, comparer2);

            foreach (TSource element in source)
            {
                dictionary.Add(key1Selector(element), key2Selector(element), elementSelector(element));
            }

            return(dictionary);
        }
        /// <summary>
        /// Creates a nested dictionary from an ienumerable according to a specified key selectors function, comparers, and an element selector function.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <typeparam name="TKey1">The type of the key returned by key1Selector for level 1.</typeparam>
        /// <typeparam name="TKey2">The type of the key returned by key2Selector for level 2.</typeparam>
        /// <typeparam name="TKey3">The type of the key returned by key3Selector for level 3.</typeparam>
        /// <typeparam name="TKey4">The type of the key returned by key4Selector for level 4.</typeparam>
        /// <typeparam name="TKey5">The type of the key returned by key5Selector for level 5.</typeparam>
        /// <typeparam name="TKey6">The type of the key returned by key6Selector for level 6.</typeparam>
        /// <typeparam name="TKey7">The type of the key returned by key7Selector for level 7.</typeparam>
        /// <typeparam name="TKey8">The type of the key returned by key8Selector for level 8.</typeparam>
        /// <typeparam name="TElement">The type of the value returned by elementSelector.</typeparam>
        /// <param name="source">An ienumerable to create a nested dictionary from.</param>
        /// <param name="key1Selector">A function to extract a key for level 1 from each element.</param>
        /// <param name="key2Selector">A function to extract a key for level 2 from each element.</param>
        /// <param name="key3Selector">A function to extract a key for level 3 from each element.</param>
        /// <param name="key4Selector">A function to extract a key for level 4 from each element.</param>
        /// <param name="key5Selector">A function to extract a key for level 5 from each element.</param>
        /// <param name="key6Selector">A function to extract a key for level 6 from each element.</param>
        /// <param name="key7Selector">A function to extract a key for level 7 from each element.</param>
        /// <param name="key8Selector">A function to extract a key for level 8 from each element.</param>
        /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
        /// <param name="comparer1">An comparer to compare keys on level 1.</param>
        /// <param name="comparer2">An comparer to compare keys on level 2.</param>
        /// <param name="comparer3">An comparer to compare keys on level 3.</param>
        /// <param name="comparer4">An comparer to compare keys on level 4.</param>
        /// <param name="comparer5">An comparer to compare keys on level 5.</param>
        /// <param name="comparer6">An comparer to compare keys on level 6.</param>
        /// <param name="comparer7">An comparer to compare keys on level 7.</param>
        /// <param name="comparer8">An comparer to compare keys on level 8.</param>
        /// <returns>A nested dictionary that contains values of type TElement selected from the input sequence.</returns>
        /// <exception cref="ArgumentNullException">source or some of keySelectors or elementSelector is null.-or- some of keySelectors produces a key that is null.</exception>
        /// <exception cref="ArgumentException">Some of keySelectors produces duplicate keys for two elements.</exception>
        public static NestedDictionary <TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TKey8, TElement> ToNestedDictionary <TSource, TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TKey8, TElement>(this IEnumerable <TSource> source, Func <TSource, TKey1> key1Selector, Func <TSource, TKey2> key2Selector, Func <TSource, TKey3> key3Selector, Func <TSource, TKey4> key4Selector, Func <TSource, TKey5> key5Selector, Func <TSource, TKey6> key6Selector, Func <TSource, TKey7> key7Selector, Func <TSource, TKey8> key8Selector, Func <TSource, TElement> elementSelector, IEqualityComparer <TKey1> comparer1, IEqualityComparer <TKey2> comparer2, IEqualityComparer <TKey3> comparer3, IEqualityComparer <TKey4> comparer4, IEqualityComparer <TKey5> comparer5, IEqualityComparer <TKey6> comparer6, IEqualityComparer <TKey7> comparer7, IEqualityComparer <TKey8> comparer8)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (key1Selector == null)
            {
                throw new ArgumentNullException(nameof(key1Selector));
            }
            if (key2Selector == null)
            {
                throw new ArgumentNullException(nameof(key2Selector));
            }
            if (key3Selector == null)
            {
                throw new ArgumentNullException(nameof(key3Selector));
            }
            if (key4Selector == null)
            {
                throw new ArgumentNullException(nameof(key4Selector));
            }
            if (key5Selector == null)
            {
                throw new ArgumentNullException(nameof(key5Selector));
            }
            if (key6Selector == null)
            {
                throw new ArgumentNullException(nameof(key6Selector));
            }
            if (key7Selector == null)
            {
                throw new ArgumentNullException(nameof(key7Selector));
            }
            if (key8Selector == null)
            {
                throw new ArgumentNullException(nameof(key8Selector));
            }
            if (elementSelector == null)
            {
                throw new ArgumentNullException(nameof(elementSelector));
            }

            NestedDictionary <TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TKey8, TElement> dictionary = new NestedDictionary <TKey1, TKey2, TKey3, TKey4, TKey5, TKey6, TKey7, TKey8, TElement>(comparer1, comparer2, comparer3, comparer4, comparer5, comparer6, comparer7, comparer8);

            foreach (TSource element in source)
            {
                dictionary.Add(key1Selector(element), key2Selector(element), key3Selector(element), key4Selector(element), key5Selector(element), key6Selector(element), key7Selector(element), key8Selector(element), elementSelector(element));
            }

            return(dictionary);
        }
Example #3
0
        private static void AddValue(NestedDictionary <string, int, bool, decimal> dictionary)
        {
            Console.WriteLine("---Add Value---");

            dictionary.Add("York", 2017, true, 15m);
            dictionary.Add("York", 2016, true, 15m);

            dictionary.Add("Phoenix", 2016, new NestedDictionary <bool, decimal>()
            {
                { false, 12m }
            });

            // Throws argument exception - key already in the dictionary
            try
            {
                dictionary.Add("Phoenix", 2016, false, 10m);
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine(ex.Message);
            }

            // Throws argument exception - key already in the dictionary
            try
            {
                dictionary.Add("York", new NestedDictionary <int, bool, decimal>()
                {
                    { 2011, false, 5m }
                });
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine(ex.Message);
            }

            PrintDictionary(dictionary);
        }
Example #4
0
        public void WriteModule(TextWriter output, TemplateLibrary library, Data.Module module)
        {
            var baseDict = new Dictionary <string, IInsertable>()
            {
                { "module_name", new StringLiteral(module.Name) },
            };

            var objectsContainer = new InsertableContainer()
            {
                AutoIndentAndNewline = true
            };

            foreach (var type in module.Types.Values)
            {
                if (!library.CustomTypeTemplates.TryGetValue(type.Name, out TemplateLibrary.TypeTemplates typeTemplates))
                {
                    typeTemplates = library.GenericTypeTemplates;
                }

                var typeDict = new NestedDictionary <string, IInsertable>(baseDict)
                {
                    { "obj_name", new StringLiteral(type.Name) },
                };
                typeDict.Add("obj_type", new TemplateInsert(typeTemplates.TypeNameTemplate, typeDict));


                // Functions
                var functionsContainer = new InsertableContainer()
                {
                    AutoIndentAndNewline = true
                };

                // Read and write functions for this type

                var readCallContainer = new InsertableContainer()
                {
                    AutoIndentAndNewline = true
                };

                var writeCallContainer = new InsertableContainer()
                {
                    AutoIndentAndNewline = true
                };

                // Fields
                var fieldsContainer = new InsertableContainer()
                {
                    AutoIndentAndNewline = true
                };

                foreach (var field in type.Fields)
                {
                    if (!library.CustomTypeTemplates.TryGetValue(field.Type.Name, out TemplateLibrary.TypeTemplates fieldTypeTemplates))
                    {
                        fieldTypeTemplates = library.GenericTypeTemplates;
                    }

                    var fieldDict = new NestedDictionary <string, IInsertable>(typeDict)
                    {
                        { "field_type", new TemplateInsert(fieldTypeTemplates.TypeNameTemplate, new NestedDictionary <string, IInsertable>(baseDict)
                            {
                                { "obj_name", new StringLiteral(field.Type.Name) }
                            }) },
                        { "field_name", new StringLiteral(field.Name) },
                        { "field_byte_offset", new StringLiteral(field.ByteOffset.ToString()) },
                        { "field_bit_offset", new StringLiteral(field.BitOffset.ToString()) },
                    };

                    readCallContainer.Insertables.Add(new TemplateInsert(fieldTypeTemplates.ReadCall, fieldDict));
                    writeCallContainer.Insertables.Add(new TemplateInsert(fieldTypeTemplates.WriteCall, fieldDict));
                    fieldsContainer.Insertables.Add(new TemplateInsert(typeTemplates.TypeFieldTemplate, fieldDict));
                }

                var readFuncDict = new NestedDictionary <string, IInsertable>(typeDict)
                {
                    { "read_fields", readCallContainer }
                };
                functionsContainer.Insertables.Add(new TemplateInsert(typeTemplates.ReadFunction, readFuncDict));

                var writeFuncDict = new NestedDictionary <string, IInsertable>(typeDict)
                {
                    { "write_fields", writeCallContainer }
                };
                functionsContainer.Insertables.Add(new TemplateInsert(typeTemplates.WriteFunction, writeFuncDict));


                typeDict.Add("fields", fieldsContainer);
                typeDict.Add("functions", functionsContainer);

                // Write out
                objectsContainer.Insertables.Add(new TemplateInsert(typeTemplates.TypeTemplate, typeDict));
            }

            var fileDict = new NestedDictionary <string, IInsertable>(baseDict)
            {
                { "constants", new StringLiteral("") },
                { "objects", objectsContainer }
            };

            library.FileTemplate.Apply(output, fileDict, 0);
        }