From b6c478dcff4cfd9ac804cd0739ca83f4396ee48e Mon Sep 17 00:00:00 2001 From: Adrian Date: Sun, 21 Feb 2016 22:31:43 +0100 Subject: [PATCH 1/2] Eager evaluation in Enumerables, other minor changes * Eager evaluation of iterating functions, they are already in System.Linq * Remove index parameters in functions * Create array or list of anonymous objects * Dictionary creation * ToArray and ToList --- src/main/AdrianKousz.Util/Enumerables.cs | 132 +++++++++++++++++------ 1 file changed, 98 insertions(+), 34 deletions(-) diff --git a/src/main/AdrianKousz.Util/Enumerables.cs b/src/main/AdrianKousz.Util/Enumerables.cs index 6567f51..a8c7ade 100644 --- a/src/main/AdrianKousz.Util/Enumerables.cs +++ b/src/main/AdrianKousz.Util/Enumerables.cs @@ -10,30 +10,53 @@ namespace AdrianKousz.Util { #region Fillers - public static T[] Fill(this T[] array) where T : new() { return Fill(array, i => new T()); } - public static T[] Fill(this T[] array, T value) { return Fill(array, i => value); } - public static T[] Fill(this T[] array, Func f) { return Fill(array, i => f()); } - public static T[] Fill(this T[] array, Func f) + public static T[] Fill(this T[] array) where T : new() { return Fill(array, () => new T()); } + public static T[] Fill(this T[] array, T value) { return Fill(array, () => value); } + public static T[] Fill(this T[] array, Func f) { - var min = array.GetLowerBound(0); - var max = array.GetUpperBound(0); - for (var i = min; i <= max; i++) - array[i] = f(i); + var len = array.Length; + for (var i = 0; i < len; i++) array[i] = f(); return array; } - public static IList Fill(this IList list, int count) where T : new() { return Fill(list, i => new T(), count); } - public static IList Fill(this IList list, T value, int count) { return Fill(list, i => value, count); } - public static IList Fill(this IList list, Func f, int count) { return Fill(list, i => f(), count); } - public static IList Fill(this IList list, Func f, int count) + public static ICollection Fill(this ICollection list, int count) where T : new() { return Fill(list, count, () => new T()); } + public static ICollection Fill(this ICollection list, int count, T value) { return Fill(list, count, () => value); } + public static ICollection Fill(this ICollection list, int count, Func f) { - for (var i = 0; i < count; i++) - list.Add(f(i)); + for (var i = 0; i < count; i++) list.Add(f()); return list; } #endregion + #region Anonymous Type Helpers + + public static T[] CreateArray(this T example, int count) + { + return new T[count]; + } + + public static List CreateList(this T example) + { + return new List(); + } + + #endregion + + #region Materializers + + public static List ToList(this IEnumerable source) + { + return source as List ?? new List(source); + } + + public static T[] ToArray(this IEnumerable source) + { + return source as T[] ?? ToList(source).ToArray(); + } + + #endregion + #region Functional Classics public static int IndexOf(this IEnumerable source, T value, Func comparer) @@ -46,58 +69,99 @@ namespace AdrianKousz.Util return -1; } - public static IEnumerable ForEach(this IEnumerable source, Action f) { return ForEach(source, (i, x) => f(x)); } - public static IEnumerable ForEach(this IEnumerable source, Action f) + public static IEnumerable ForEach(this IEnumerable source, Action f) { - var i = 0; - foreach (var el in source) f(i++, el); + foreach (var el in source) f(el); return source; } // Linq: Select public static IEnumerable Map(this IEnumerable source, Func f) { - foreach (var el in source) yield return f(el); + var result = GetList(source); + foreach (var el in source) result.Add(f(el)); + return result; } // Linq: Where public static IEnumerable Filter(this IEnumerable source, Func f) { - foreach (var el in source) if (f(el)) yield return el; + var result = GetList(source); + foreach (var el in source) if (f(el)) result.Add(el); + return result; } public static TResult FoldL(this IEnumerable source, TResult initial, Action f) { return FoldL(source, initial, (folded, el) => { f(folded, el); return folded; }); } public static TResult FoldL(this IEnumerable source, TResult initial, Func f) { - var folded = initial; - foreach (var el in source) folded = f(folded, el); - return folded; + var result = initial; + foreach (var el in source) result = f(result, el); + return result; } // Linq: Aggregate public static T FoldL1(this IEnumerable source, Func f) { - using (var en = source.GetEnumerator()) { + using (var en = source.GetEnumerator()) + { if (!en.MoveNext()) throw new InvalidOperationException("No elements"); - T folded = en.Current; - while (en.MoveNext()) folded = f(folded, en.Current); - return folded; + T result = en.Current; + while (en.MoveNext()) result = f(result, en.Current); + return result; } } + #endregion + + #region Zippers + + public static IDictionary ToDictionary(this IEnumerable ks, IEnumerable vs) + { + var result = new Dictionary(); + using (var en1 = ks.GetEnumerator()) + using (var en2 = vs.GetEnumerator()) + { + while (en1.MoveNext() && en2.MoveNext()) + result[en1.Current] = en2.Current; + } + return result; + } + + public static IDictionary ToDictionary(this IEnumerable source) + { + var result = new Dictionary(); + var iskey = true; + var k = default(T); + foreach (var el in source) + if (iskey = !iskey) result[k] = el; + else k = el; + return result; + } + public static IEnumerable Zip(this IEnumerable s1, IEnumerable s2, Func f) { - using (var en1 = s1.GetEnumerator()) { - using (var en2 = s2.GetEnumerator()) { - while (en1.MoveNext() && en2.MoveNext()) { - yield return f(en1.Current, en2.Current); - } - } + var result = GetList(s1); + using (var en1 = s1.GetEnumerator()) + using (var en2 = s2.GetEnumerator()) + { + while (en1.MoveNext() && en2.MoveNext()) + result.Add(f(en1.Current, en2.Current)); } + return result; + } + + #endregion + + #region Implementation Detail + + private static List GetList(IEnumerable source) + { + var collection = source as ICollection; + var length = collection == null ? 4 : collection.Count; + return new List(length); } #endregion } } - From 2b0d56b1a2d2abd2f5279b4a8712b7d9d61c8e97 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 22 Feb 2016 16:25:44 +0100 Subject: [PATCH 2/2] ForEach for dictionaries --- src/main/AdrianKousz.Util/Enumerables.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/AdrianKousz.Util/Enumerables.cs b/src/main/AdrianKousz.Util/Enumerables.cs index a8c7ade..993d8e2 100644 --- a/src/main/AdrianKousz.Util/Enumerables.cs +++ b/src/main/AdrianKousz.Util/Enumerables.cs @@ -75,6 +75,12 @@ namespace AdrianKousz.Util return source; } + public static IDictionary ForEach(this IDictionary source, Action f) + { + foreach (var el in source) f(el.Key, el.Value); + return source; + } + // Linq: Select public static IEnumerable Map(this IEnumerable source, Func f) {