/// <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); }
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); }
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); }