using System; using System.Collections.Generic; namespace JM.LinqFaster { public static partial class LinqFaster { // ----------------------------- Arrays ------------------ /// /// Combines Where and Aggregate for optimal performance /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static T WhereAggregateF(this T[] source, Func predicate, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } if (func == null) { throw Error.ArgumentNull("func"); } var result = default(T); int i = 0; for (; i < source.Length; i++) { if (predicate(source[i])) { result = source[i]; i++; break; } } for (; i < source.Length; i++) { if (predicate(source[i])) { result = func(result, source[i]); } } return result; } /// /// Combines Where and Aggregate with index for optimal performance /// /// The input to filter then aggregate. /// The function to filter the input sequence and it's index with. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static T WhereAggregateF(this T[] source, Func predicate, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } var result = default(T); int i = 0; for (; i < source.Length; i++) { if (predicate(source[i], i)) { result = source[i]; i++; break; } } for (; i < source.Length; i++) { if (predicate(source[i], i)) { result = func(result, source[i]); } } return result; } /// /// Combines Where and Aggregate for optimal performance with a starting seed. /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The initial value to aggregate on. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static TAccumulate WhereAggregateF(this TSource[] source, Func predicate, TAccumulate seed, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (func == null) { throw Error.ArgumentNull("func"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } TAccumulate result = seed; foreach (var v in source) { if (predicate(v)) result = func(result, v); } return result; } /// /// Combines Where and Aggregate for optimal performance with a starting seed and a result transformation. /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The initial value to aggregate on. /// The function to aggregate the filtered seqeuence. /// A function to transform the final result. /// The filtered then aggregated then transformed sequence. public static TResult WhereAggregateF(this TSource[] source, Func predicate, TAccumulate seed, Func func, Func resultSelector) { if (source == null) { throw Error.ArgumentNull("source"); } if (func == null) { throw Error.ArgumentNull("func"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } if (resultSelector == null) { throw Error.ArgumentNull("resultSelector"); } TAccumulate result = seed; int count = 0; foreach (var v in source) { if (predicate(v)) { result = func(result, v); count++; } } return resultSelector(result); } // --------------------------- Lists ------------------------- /// /// Combines Where and Aggregate for optimal performance /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static T WhereAggregateF(this List source, Func predicate, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } if (func == null) { throw Error.ArgumentNull("func"); } var result = default(T); int i = 0; for (; i < source.Count; i++) { if (predicate(source[i])) { result = source[i]; i++; break; } } for (; i < source.Count; i++) { if (predicate(source[i])) { result = func(result, source[i]); } } return result; } /// /// Combines Where and Aggregate with index for optimal performance /// /// The input to filter then aggregate. /// The function to filter the input sequence and it's index with. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static T WhereAggregateF(this List source, Func predicate, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } var result = default(T); int i = 0; for (; i < source.Count; i++) { if (predicate(source[i], i)) { result = source[i]; i++; break; } } for (; i < source.Count; i++) { if (predicate(source[i], i)) { result = func(result, source[i]); } } return result; } /// /// Combines Where and Aggregate for optimal performance with a starting seed. /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The initial value to aggregate on. /// The function to aggregate the filtered seqeuence. /// The filtered then aggregated sequence. public static TAccumulate WhereAggregateF(this List source, Func predicate, TAccumulate seed, Func func) { if (source == null) { throw Error.ArgumentNull("source"); } if (func == null) { throw Error.ArgumentNull("func"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } TAccumulate result = seed; for (int i = 0; i < source.Count; i++) { var v = source[i]; if (predicate(v)) result = func(result, v); } return result; } /// /// Combines Where and Aggregate for optimal performance with a starting seed and a result transformation. /// /// The input to filter then aggregate. /// The function to filter the input sequence with. /// The initial value to aggregate on. /// The function to aggregate the filtered seqeuence. /// A function to transform the final result. /// The filtered then aggregated then transformed sequence. public static TResult WhereAggregateF(this List source, Func predicate, TAccumulate seed, Func func, Func resultSelector) { if (source == null) { throw Error.ArgumentNull("source"); } if (func == null) { throw Error.ArgumentNull("func"); } if (resultSelector == null) { throw Error.ArgumentNull("resultSelector"); } TAccumulate result = seed; for (int i = 0; i < source.Count; i++) { var v = source[i]; if (predicate(v)) result = func(result, v); } return resultSelector(result); } } }