diff --git a/ShittyLINQ/ToLookup.cs b/ShittyLINQ/ToLookup.cs new file mode 100644 index 0000000..3d14978 --- /dev/null +++ b/ShittyLINQ/ToLookup.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; + +namespace ShittyLINQ +{ + public static partial class Extensions + { + /// + /// Creates a lookup from an IEnumerable + /// + /// Set of elements to be converted to lookup + /// Key selector to determine the key of the lookup + /// Source type + /// Key type + /// A lookup made from source + /// If source, keySelector or element Selector is null + public static Dictionary> ToLookup( + this IEnumerable source, + Func keySelector) + { + return ToLookup(source, keySelector, t => t, EqualityComparer.Default); + } + + /// + /// Creates a lookup from an IEnumerable + /// + /// Set of elements to be converted to lookup + /// Key selector to determine the key of the lookup + /// Element selector to determine the value of the lookup + /// Source type + /// Key type + /// Value type + /// A lookup made from source + /// If source, keySelector or element Selector is null + public static Dictionary> ToLookup( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + return source.ToLookup(keySelector, elementSelector, EqualityComparer.Default); + } + + /// + /// Creates a lookup from an IEnumerable + /// + /// Set of elements to be converted to lookup + /// Key selector to determine the key of the lookup + /// Comparer to be used to determine equality between elements + /// Source type + /// Key type + /// A lookup made from source + /// If source, keySelector or element Selector is null + public static Dictionary> ToLookup( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) + { + return ToLookup(source, keySelector, t => t, comparer); + } + + /// + /// Creates a lookup from an IEnumerable + /// + /// Set of elements to be converted to lookup + /// Key selector to determine the key of the lookup + /// Element selector to determine the value of the lookup + /// Comparer to be used to determine equality between elements + /// Source type + /// Key type + /// Value type + /// A lookup made from source + /// If source, keySelector or element Selector is null + public static Dictionary> ToLookup( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null || keySelector == null || elementSelector == null) throw new ArgumentNullException(); + + List tempList; + IEnumerable existingValues; + + Dictionary> ret = new Dictionary>(comparer ?? EqualityComparer.Default); + foreach (TSource item in source) + { + existingValues = ret.GetValueOrDefault(keySelector(item)); + if (existingValues == null) + { + tempList = new List(); + } + else + { + tempList = existingValues.ToList(); + ret.Remove(keySelector(item)); + } + tempList.Add(elementSelector(item)); + ret.Add(keySelector(item), tempList); + + } + return ret; + } + } + +} \ No newline at end of file diff --git a/ShittyLinqTests/ToLookupTests.cs b/ShittyLinqTests/ToLookupTests.cs new file mode 100644 index 0000000..cc38edb --- /dev/null +++ b/ShittyLinqTests/ToLookupTests.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ShittyLINQ; +using ShittyTests.TestHelpers; + +namespace ShittyTests +{ + [TestClass] + public class ToLookupTests + { + [TestMethod] + public void ToLookup_Numbers() + { + IEnumerable numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + var result = numbers.ToLookup(x => x, x => true); + + Assert.AreEqual(result.Count, 9); + + foreach (int number in numbers) + { + Assert.IsTrue(result.ContainsKey(number)); + } + } + + [TestMethod] + public void ToLookup_Person() + { + var adam = new Person("Adam", 20, "Arquitech", "Amber"); + var brian = new Person("Brian", 45, "Arquitech", "Blue"); + var charles = new Person("Charles", 33, "Arquitech", "Cyan"); + var dani = new Person("Dani", 33, "Developer", "Deep Purple"); + + IEnumerable people = new[] { adam, brian, charles, dani }; + + var result = people.ToLookup(person => person.Age); + + Assert.AreEqual(result.TryGetValue(brian.Age, out var expectedBrian), true); + Assert.IsNotNull(expectedBrian); + } + } +} \ No newline at end of file