5 // Marek Safar (marek.safar@gmail.com)
6 // Antonello Provenzano <antonello@deveel.com>
7 // Alejandro Serrano "Serras" (trupill@yahoo.es)
8 // Jb Evain (jbevain@novell.com)
10 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 // precious: http://www.hookedonlinq.com
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Collections.ObjectModel;
41 public static class Enumerable
48 class PredicateOf<T> {
49 public static readonly Func<T, bool> Always = (t) => true;
54 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
56 Check.SourceAndFunc (source, func);
58 // custom foreach so that we can efficiently throw an exception
59 // if zero elements and treat the first element differently
60 using (var enumerator = source.GetEnumerator ()) {
61 if (!enumerator.MoveNext ())
62 throw new InvalidOperationException ("No elements in source list");
64 TSource folded = enumerator.Current;
65 while (enumerator.MoveNext ())
66 folded = func (folded, enumerator.Current);
71 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
72 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
74 Check.SourceAndFunc (source, func);
76 TAccumulate folded = seed;
77 foreach (TSource element in source)
78 folded = func (folded, element);
83 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
85 Check.SourceAndFunc (source, func);
86 if (resultSelector == null)
87 throw new ArgumentNullException ("resultSelector");
90 foreach (var e in source)
91 result = func (result, e);
93 return resultSelector (result);
100 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
102 Check.SourceAndPredicate (source, predicate);
104 foreach (var element in source)
105 if (!predicate (element))
115 public static bool Any<TSource> (this IEnumerable<TSource> source)
117 Check.Source (source);
119 using (var enumerator = source.GetEnumerator ())
120 return enumerator.MoveNext ();
123 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
125 Check.SourceAndPredicate (source, predicate);
127 foreach (TSource element in source)
128 if (predicate (element))
138 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
147 public static double Average (this IEnumerable<int> source)
149 return Average<int, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
152 public static double Average (this IEnumerable<long> source)
154 return Average<long, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
157 public static double Average (this IEnumerable<double> source)
159 return Average<double, double, double> (source, (a, b) => a + b, (a, b) => a / b);
162 public static float Average (this IEnumerable<float> source)
164 return Average<float, double, float> (source, (a, b) => a + b, (a, b) => (float) a / (float) b);
167 public static decimal Average (this IEnumerable<decimal> source)
169 return Average<decimal, decimal, decimal> (source, (a, b) => a + b, (a, b) => a / b);
172 static TResult Average<TElement, TAggregate, TResult> (this IEnumerable<TElement> source,
173 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
174 where TElement : struct
175 where TAggregate : struct
176 where TResult : struct
178 Check.Source (source);
180 var total = default (TAggregate);
182 foreach (var element in source) {
183 total = func (total, element);
188 throw new InvalidOperationException ();
190 return result (total, counter);
193 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
194 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
195 where TElement : struct
196 where TAggregate : struct
197 where TResult : struct
199 Check.Source (source);
201 var total = default (TAggregate);
203 foreach (var element in source) {
204 if (!element.HasValue)
207 total = func (total, element.Value);
214 return new TResult? (result (total, counter));
217 public static double? Average (this IEnumerable<int?> source)
219 Check.Source (source);
221 return source.AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
224 public static double? Average (this IEnumerable<long?> source)
226 Check.Source (source);
228 return source.AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => a / b);
231 public static double? Average (this IEnumerable<double?> source)
233 Check.Source (source);
235 return source.AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
238 public static decimal? Average (this IEnumerable<decimal?> source)
240 Check.Source (source);
242 return source.AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
245 public static float? Average (this IEnumerable<float?> source)
247 Check.Source (source);
249 return source.AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
252 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
254 Check.SourceAndSelector (source, selector);
256 return source.Select (selector).Average<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
259 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
261 Check.SourceAndSelector (source, selector);
263 return source.Select (selector).AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
266 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
268 Check.SourceAndSelector (source, selector);
270 return source.Select (selector).Average<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
273 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
275 Check.SourceAndSelector (source, selector);
277 return source.Select (selector).AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
280 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
282 Check.SourceAndSelector (source, selector);
284 return source.Select (selector).Average<double, double, double> ((a, b) => a + b, (a, b) => a / b);
287 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
289 Check.SourceAndSelector (source, selector);
291 return source.Select (selector).AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
294 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
296 Check.SourceAndSelector (source, selector);
298 return source.Select (selector).Average<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
301 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
303 Check.SourceAndSelector (source, selector);
305 return source.Select (selector).AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
308 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
310 Check.SourceAndSelector (source, selector);
312 return source.Select (selector).Average<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
315 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
317 Check.SourceAndSelector (source, selector);
319 return source.Select (selector).AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
326 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
328 Check.Source (source);
330 return CreateCastIterator<TResult> (source);
333 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
335 foreach (object element in source)
336 yield return (TResult) element;
343 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
345 Check.FirstAndSecond (first, second);
347 return CreateConcatIterator (first, second);
350 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
352 foreach (TSource element in first)
353 yield return element;
354 foreach (TSource element in second)
355 yield return element;
362 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
364 var collection = source as ICollection<TSource>;
365 if (collection != null)
366 return collection.Contains (value);
368 return Contains<TSource> (source, value, null);
371 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
373 Check.Source (source);
375 if (comparer == null)
376 comparer = EqualityComparer<TSource>.Default;
378 foreach (var element in source)
379 if (comparer.Equals (element, value))
388 public static int Count<TSource> (this IEnumerable<TSource> source)
390 Check.Source (source);
392 var collection = source as ICollection<TSource>;
393 if (collection != null)
394 return collection.Count;
397 using (var enumerator = source.GetEnumerator ())
398 while (enumerator.MoveNext ())
404 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
406 Check.SourceAndSelector (source, selector);
409 foreach (var element in source)
410 if (selector (element))
418 #region DefaultIfEmpty
420 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
422 return DefaultIfEmpty (source, default (TSource));
425 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
427 Check.Source (source);
429 return CreateDefaultIfEmptyIterator (source, defaultValue);
432 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
435 foreach (TSource item in source) {
441 yield return defaultValue;
448 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
450 return Distinct<TSource> (source, null);
453 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
455 Check.Source (source);
457 if (comparer == null)
458 comparer = EqualityComparer<TSource>.Default;
460 return CreateDistinctIterator (source, comparer);
463 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
465 var items = new HashSet<TSource> (comparer);
466 foreach (var element in source) {
467 if (! items.Contains (element)) {
469 yield return element;
478 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
482 foreach (var element in source) {
483 if (index == counter++)
487 if (fallback == Fallback.Throw)
488 throw new ArgumentOutOfRangeException ();
490 return default (TSource);
493 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
495 Check.Source (source);
498 throw new ArgumentOutOfRangeException ();
500 var list = source as IList<TSource>;
504 return source.ElementAt (index, Fallback.Throw);
509 #region ElementAtOrDefault
511 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
513 Check.Source (source);
516 return default (TSource);
518 var list = source as IList<TSource>;
520 return index < list.Count ? list [index] : default (TSource);
522 return source.ElementAt (index, Fallback.Default);
529 public static IEnumerable<TResult> Empty<TResult> ()
531 return new TResult [0];
538 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
540 return Except (first, second, null);
543 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
545 Check.FirstAndSecond (first, second);
547 if (comparer == null)
548 comparer = EqualityComparer<TSource>.Default;
550 return CreateExceptIterator (first, second, comparer);
553 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
555 var items = new HashSet<TSource> (second, comparer);
556 foreach (var element in first) {
557 if (!items.Contains (element, comparer))
558 yield return element;
566 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
568 foreach (var element in source)
569 if (predicate (element))
572 if (fallback == Fallback.Throw)
573 throw new InvalidOperationException ();
575 return default (TSource);
578 public static TSource First<TSource> (this IEnumerable<TSource> source)
580 Check.Source (source);
582 return source.First (PredicateOf<TSource>.Always, Fallback.Throw);
585 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
587 Check.SourceAndPredicate (source, predicate);
589 return source.First (predicate, Fallback.Throw);
594 #region FirstOrDefault
596 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
598 Check.Source (source);
600 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
603 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
605 Check.SourceAndPredicate (source, predicate);
607 return source.First (predicate, Fallback.Default);
614 private static List<T> ContainsGroup<K, T> (
615 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
617 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
618 foreach (KeyValuePair<K, List<T>> value in items) {
619 if (comparerInUse.Equals (value.Key, key))
625 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
626 Func<TSource, TKey> keySelector)
628 return GroupBy<TSource, TKey> (source, keySelector, null);
631 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
632 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
634 Check.SourceAndKeySelector (source, keySelector);
636 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
637 List<TSource> nullList = new List<TSource> ();
639 int nullCounter = -1;
641 foreach (TSource element in source) {
642 TKey key = keySelector (element);
644 nullList.Add (element);
645 if (nullCounter == -1) {
646 nullCounter = counter;
650 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
652 group = new List<TSource> ();
653 groups.Add (key, group);
661 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
662 if (counter == nullCounter) {
663 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
664 yield return nullGroup;
667 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
668 yield return grouping;
674 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
675 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
677 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
680 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
681 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
683 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
685 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
686 List<TElement> nullList = new List<TElement> ();
688 int nullCounter = -1;
690 foreach (TSource item in source) {
691 TKey key = keySelector (item);
692 TElement element = elementSelector (item);
694 nullList.Add (element);
695 if (nullCounter == -1) {
696 nullCounter = counter;
700 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
702 group = new List<TElement> ();
703 groups.Add (key, group);
711 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
712 if (counter == nullCounter) {
713 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
714 yield return nullGroup;
717 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
718 yield return grouping;
723 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
724 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
725 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
727 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
730 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
731 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
732 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
733 IEqualityComparer<TKey> comparer)
735 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
736 source, keySelector, elementSelector, comparer);
738 foreach (IGrouping<TKey, TElement> group in groups)
739 yield return resultSelector (group.Key, group);
742 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
743 Func<TSource, TKey> keySelector,
744 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
746 return GroupBy (source, keySelector, resultSelector, null);
749 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
750 Func<TSource, TKey> keySelector,
751 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
752 IEqualityComparer<TKey> comparer)
754 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
756 foreach (IGrouping<TKey, TSource> group in groups)
757 yield return resultSelector (group.Key, group);
764 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
765 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
766 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
768 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
771 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
772 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
773 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
774 IEqualityComparer<TKey> comparer)
776 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
778 if (comparer == null)
779 comparer = EqualityComparer<TKey>.Default;
781 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
782 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
783 foreach (U element in inner)
785 K innerKey = innerKeySelector (element);
786 if (!innerKeys.ContainsKey (innerKey))
787 innerKeys.Add (innerKey, new List<U> ());
788 innerKeys[innerKey].Add (element);
791 foreach (TOuter element in outer) {
792 TKey outerKey = outerKeySelector (element);
793 if (innerKeys.Contains (outerKey))
794 yield return resultSelector (element, innerKeys [outerKey]);
796 yield return resultSelector (element, Empty<TInner> ());
804 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
806 return Intersect (first, second, null);
809 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
811 Check.FirstAndSecond (first, second);
813 if (comparer == null)
814 comparer = EqualityComparer<TSource>.Default;
816 return CreateIntersectIterator (first, second, comparer);
819 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
821 var items = new HashSet<TSource> (second, comparer);
822 foreach (TSource element in first) {
823 if (items.Contains (element))
824 yield return element;
832 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
833 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
834 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
836 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
838 if (comparer == null)
839 comparer = EqualityComparer<TKey>.Default;
841 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
842 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
843 foreach (U element in inner)
845 K innerKey = innerKeySelector (element);
846 if (!innerKeys.ContainsKey (innerKey))
847 innerKeys.Add (innerKey, new List<U> ());
848 innerKeys[innerKey].Add (element);
851 foreach (TOuter element in outer) {
852 TKey outerKey = outerKeySelector (element);
853 if (innerKeys.Contains (outerKey)) {
854 foreach (TInner innerElement in innerKeys [outerKey])
855 yield return resultSelector (element, innerElement);
860 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
861 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
862 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
864 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
871 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
874 var item = default (TSource);
876 foreach (var element in source) {
877 if (!predicate (element))
887 if (fallback == Fallback.Throw)
888 throw new InvalidOperationException ();
893 public static TSource Last<TSource> (this IEnumerable<TSource> source)
895 Check.Source (source);
897 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
900 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
902 Check.SourceAndPredicate (source, predicate);
904 return source.Last (predicate, Fallback.Throw);
909 #region LastOrDefault
911 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
913 Check.Source (source);
915 var list = source as IList<TSource>;
917 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
919 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
922 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
924 Check.SourceAndPredicate (source, predicate);
926 return source.Last (predicate, Fallback.Default);
933 public static long LongCount<TSource> (this IEnumerable<TSource> source)
935 Check.Source (source);
938 var array = source as TSource [];
940 return array.LongLength;
944 using (var enumerator = source.GetEnumerator ())
945 while (enumerator.MoveNext ())
951 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
953 Check.SourceAndSelector (source, selector);
956 foreach (TSource element in source)
957 if (selector (element))
967 public static int Max (this IEnumerable<int> source)
969 Check.Source (source);
971 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
974 public static long Max (this IEnumerable<long> source)
976 Check.Source (source);
978 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
981 public static double Max (this IEnumerable<double> source)
983 Check.Source (source);
985 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
988 public static float Max (this IEnumerable<float> source)
990 Check.Source (source);
992 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
995 public static decimal Max (this IEnumerable<decimal> source)
997 Check.Source (source);
999 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1002 public static int? Max (this IEnumerable<int?> source)
1004 Check.Source (source);
1006 return IterateNullable (source, int.MinValue, (a, b) => a > b);
1009 public static long? Max (this IEnumerable<long?> source)
1011 Check.Source (source);
1013 return IterateNullable (source, long.MinValue, (a, b) => a > b);
1016 public static double? Max (this IEnumerable<double?> source)
1018 Check.Source (source);
1020 return IterateNullable (source, double.MinValue, (a, b) => a > b);
1023 public static float? Max (this IEnumerable<float?> source)
1025 Check.Source (source);
1027 return IterateNullable (source, float.MinValue, (a, b) => a > b);
1030 public static decimal? Max (this IEnumerable<decimal?> source)
1032 Check.Source (source);
1034 return IterateNullable (source, decimal.MinValue, (a, b) => a > b);
1037 static T? IterateNullable<T> (IEnumerable<T?> source, T initValue, Func<T?, T?, bool> selector) where T : struct
1040 T? value = initValue;
1041 foreach (var element in source) {
1042 if (!element.HasValue)
1045 if (selector (element.Value, value))
1056 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1058 Check.Source (source);
1060 bool notAssigned = true;
1061 TSource maximum = default (TSource);
1063 foreach (TSource element in source) {
1066 notAssigned = false;
1069 if (element is IComparable<TSource>)
1070 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1071 else if (element is System.IComparable)
1072 comparison = ((System.IComparable) element).CompareTo (maximum);
1074 throw new ArgumentNullException ();
1083 throw new InvalidOperationException ();
1088 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1090 Check.SourceAndSelector (source, selector);
1092 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1095 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1097 Check.SourceAndSelector (source, selector);
1099 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1102 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1104 Check.SourceAndSelector (source, selector);
1106 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1109 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1111 Check.SourceAndSelector (source, selector);
1113 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1116 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1118 Check.SourceAndSelector (source, selector);
1120 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1123 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1126 foreach (var element in source) {
1127 initValue = selector (element, initValue);
1132 throw new InvalidOperationException ();
1137 static U? IterateNullable<T, U> (IEnumerable<T> source, U initialValue, Func<T, U?, U?> selector) where U : struct
1140 U? value = initialValue;
1141 foreach (var element in source) {
1142 value = selector (element, value);
1143 if (!value.HasValue)
1155 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1157 Check.SourceAndSelector (source, selector);
1159 return IterateNullable (source, int.MinValue, (a, b) => {
1160 var v = selector (a); return v > b ? v : b;
1164 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1166 Check.SourceAndSelector (source, selector);
1168 return IterateNullable (source, long.MinValue, (a, b) => {
1169 var v = selector (a); return v > b ? v : b;
1173 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1175 Check.SourceAndSelector (source, selector);
1177 return IterateNullable (source, double.MinValue, (a, b) => {
1178 var v = selector (a); return v > b ? v : b;
1182 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1184 Check.SourceAndSelector (source, selector);
1186 return IterateNullable (source, float.MinValue, (a, b) => {
1187 var v = selector (a); return v > b ? v : b;
1191 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1193 Check.SourceAndSelector (source, selector);
1195 return IterateNullable (source, decimal.MinValue, (a, b) => {
1196 var v = selector (a); return v > b ? v : b;
1200 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1202 Check.SourceAndSelector (source, selector);
1204 bool notAssigned = true;
1205 TResult maximum = default (TResult);
1207 foreach (TSource item in source) {
1208 TResult element = selector (item);
1211 notAssigned = false;
1214 if (element is IComparable<TResult>)
1215 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1216 else if (element is System.IComparable)
1217 comparison = ((System.IComparable) element).CompareTo (maximum);
1219 throw new ArgumentNullException ();
1228 throw new InvalidOperationException ();
1237 public static int Min (this IEnumerable<int> source)
1239 Check.Source (source);
1241 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1244 public static long Min (this IEnumerable<long> source)
1246 Check.Source (source);
1248 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1251 public static double Min (this IEnumerable<double> source)
1253 Check.Source (source);
1255 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1258 public static float Min (this IEnumerable<float> source)
1260 Check.Source (source);
1262 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1265 public static decimal Min (this IEnumerable<decimal> source)
1267 Check.Source (source);
1269 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1272 public static int? Min (this IEnumerable<int?> source)
1274 Check.Source (source);
1276 return IterateNullable (source, int.MaxValue, (a, b) => a < b);
1279 public static long? Min (this IEnumerable<long?> source)
1281 Check.Source (source);
1283 return IterateNullable (source, long.MaxValue, (a, b) => a < b);
1286 public static double? Min (this IEnumerable<double?> source)
1288 Check.Source (source);
1290 return IterateNullable (source, double.MaxValue, (a, b) => a < b);
1293 public static float? Min (this IEnumerable<float?> source)
1295 Check.Source (source);
1297 return IterateNullable (source, float.MaxValue, (a, b) => a < b);
1300 public static decimal? Min (this IEnumerable<decimal?> source)
1302 Check.Source (source);
1304 return IterateNullable (source, decimal.MaxValue, (a, b) => a < b);
1307 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1309 Check.Source (source);
1311 bool notAssigned = true;
1312 TSource minimum = default (TSource);
1314 foreach (TSource element in source) {
1317 notAssigned = false;
1320 if (element is IComparable<TSource>)
1321 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1322 else if (element is System.IComparable)
1323 comparison = ((System.IComparable) element).CompareTo (minimum);
1325 throw new ArgumentNullException ();
1334 throw new InvalidOperationException ();
1339 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1341 Check.SourceAndSelector (source, selector);
1343 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1346 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1348 Check.SourceAndSelector (source, selector);
1350 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1353 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1355 Check.SourceAndSelector (source, selector);
1357 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1360 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1362 Check.SourceAndSelector (source, selector);
1364 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1367 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1369 Check.SourceAndSelector (source, selector);
1371 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1374 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1376 Check.SourceAndSelector (source, selector);
1378 return IterateNullable (source, int.MaxValue, (a, b) => {
1379 var v = selector (a); return v < b ? v : b;
1383 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1385 Check.SourceAndSelector (source, selector);
1387 return IterateNullable (source, long.MaxValue, (a, b) => {
1388 var v = selector (a); return v < b ? v : b;
1392 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1394 Check.SourceAndSelector (source, selector);
1396 return IterateNullable (source, float.MaxValue, (a, b) => {
1397 var v = selector (a); return v < b ? v : b;
1401 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1403 Check.SourceAndSelector (source, selector);
1405 return IterateNullable (source, double.MaxValue, (a, b) => {
1406 var v = selector (a); return v < b ? v : b;
1410 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1412 Check.SourceAndSelector (source, selector);
1414 return IterateNullable (source, decimal.MaxValue, (a, b) => {
1415 var v = selector (a); return v < b ? v : b;
1419 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1421 Check.SourceAndSelector (source, selector);
1423 bool notAssigned = true;
1424 TResult minimum = default (TResult);
1426 foreach (TSource item in source) {
1427 TResult element = selector (item);
1430 notAssigned = false;
1433 if (element is IComparable<TResult>)
1434 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1435 else if (element is System.IComparable)
1436 comparison = ((System.IComparable) element).CompareTo (minimum);
1438 throw new ArgumentNullException ();
1447 throw new InvalidOperationException ();
1456 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1458 Check.Source (source);
1460 return CreateOfTypeIterator<TResult> (source);
1463 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1465 foreach (object element in source)
1466 if (element is TResult)
1467 yield return (TResult) element;
1474 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1475 Func<TSource, TKey> keySelector)
1477 return OrderBy<TSource, TKey> (source, keySelector, null);
1480 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1481 Func<TSource, TKey> keySelector,
1482 IComparer<TKey> comparer)
1484 Check.SourceAndKeySelector (source, keySelector);
1486 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1491 #region OrderByDescending
1493 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1494 Func<TSource, TKey> keySelector)
1496 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1499 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1500 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1502 Check.SourceAndKeySelector (source, keySelector);
1504 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1511 public static IEnumerable<int> Range (int start, int count)
1514 throw new ArgumentOutOfRangeException ("count");
1516 long upto = ((long) start + count) - 1;
1518 if (upto > int.MaxValue)
1519 throw new ArgumentOutOfRangeException ();
1521 return CreateRangeIterator (start, (int) upto);
1524 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1526 for (int i = start; i <= upto; i++)
1534 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1537 throw new ArgumentOutOfRangeException ();
1539 return CreateRepeatIterator (element, count);
1542 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1544 for (int i = 0; i < count; i++)
1545 yield return element;
1552 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1554 Check.Source (source);
1556 var list = source as IList<TSource>;
1558 list = new List<TSource> (source);
1560 return CreateReverseIterator (list);
1563 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1565 for (int i = source.Count; i > 0; --i)
1566 yield return source [i - 1];
1573 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1575 Check.SourceAndSelector (source, selector);
1577 return CreateSelectIterator (source, selector);
1580 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1582 foreach (var element in source)
1583 yield return selector (element);
1586 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1588 Check.SourceAndSelector (source, selector);
1590 return CreateSelectIterator (source, selector);
1593 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1596 foreach (TSource element in source) {
1597 yield return selector (element, counter);
1606 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1608 Check.SourceAndSelector (source, selector);
1610 return CreateSelectManyIterator (source, selector);
1613 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1615 foreach (TSource element in source)
1616 foreach (TResult item in selector (element))
1620 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1622 Check.SourceAndSelector (source, selector);
1624 return CreateSelectManyIterator (source, selector);
1627 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1630 foreach (TSource element in source) {
1631 foreach (TResult item in selector (element, counter))
1637 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1638 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1640 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1642 return CreateSelectManyIterator (source, collectionSelector, selector);
1645 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1646 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1648 foreach (TSource element in source)
1649 foreach (TCollection collection in collectionSelector (element))
1650 yield return selector (element, collection);
1653 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1654 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1656 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1658 return CreateSelectManyIterator (source, collectionSelector, selector);
1661 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1662 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1665 foreach (TSource element in source)
1666 foreach (TCollection collection in collectionSelector (element, counter++))
1667 yield return selector (element, collection);
1674 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1677 var item = default (TSource);
1679 foreach (var element in source) {
1680 if (!predicate (element))
1684 throw new InvalidOperationException ();
1690 if (!found && fallback == Fallback.Throw)
1691 throw new InvalidOperationException ();
1696 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1698 Check.Source (source);
1700 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1703 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1705 Check.SourceAndPredicate (source, predicate);
1707 return source.Single (predicate, Fallback.Throw);
1712 #region SingleOrDefault
1714 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1716 Check.Source (source);
1718 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1721 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1723 Check.SourceAndPredicate (source, predicate);
1725 return source.Single (predicate, Fallback.Default);
1732 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1734 Check.Source (source);
1736 return CreateSkipIterator (source, count);
1739 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1742 foreach (var element in source) {
1746 yield return element;
1754 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1756 Check.SourceAndPredicate (source, predicate);
1758 return CreateSkipWhileIterator (source, predicate);
1761 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1765 foreach (TSource element in source) {
1767 yield return element;
1769 if (!predicate (element)) {
1770 yield return element;
1776 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1778 Check.SourceAndPredicate (source, predicate);
1780 return CreateSkipWhileIterator (source, predicate);
1783 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1788 foreach (TSource element in source) {
1790 yield return element;
1792 if (!predicate (element, counter)) {
1793 yield return element;
1804 public static int Sum (this IEnumerable<int> source)
1806 Check.Source (source);
1808 return Sum<int, int> (source, (a, b) => a + b);
1811 public static int? Sum (this IEnumerable<int?> source)
1813 Check.Source (source);
1815 return SumNullable<int?, int?> (source, (a, b) => a.HasValue ? a + b : a);
1818 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1820 Check.SourceAndSelector (source, selector);
1822 return Sum<TSource, int> (source, (a, b) => a + selector (b));
1825 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1827 Check.SourceAndSelector (source, selector);
1829 return SumNullable<TSource, int?> (source, (a, b) => {
1830 var value = selector (b);
1831 return value.HasValue ? a + value.Value : a;
1835 public static long Sum (this IEnumerable<long> source)
1837 Check.Source (source);
1839 return Sum<long, long> (source, (a, b) => a + b);
1842 public static long? Sum (this IEnumerable<long?> source)
1844 Check.Source (source);
1846 return SumNullable<long?, long?> (source, (a, b) => a.HasValue ? a + b : a);
1849 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1851 Check.SourceAndSelector (source, selector);
1853 return Sum<TSource, long> (source, (a, b) => a + selector (b));
1856 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1858 Check.SourceAndSelector (source, selector);
1860 return SumNullable<TSource, long?> (source, (a, b) => {
1861 var value = selector (b);
1862 return value.HasValue ? a + value.Value : a;
1866 public static double Sum (this IEnumerable<double> source)
1868 Check.Source (source);
1870 return Sum<double, double> (source, (a, b) => a + b);
1873 public static double? Sum (this IEnumerable<double?> source)
1875 Check.Source (source);
1877 return SumNullable<double?, double?> (source, (a, b) => a.HasValue ? a + b : a);
1880 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1882 Check.SourceAndSelector (source, selector);
1884 return Sum<TSource, double> (source, (a, b) => a + selector (b));
1887 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1889 Check.SourceAndSelector (source, selector);
1891 return SumNullable<TSource, double?> (source, (a, b) => {
1892 var value = selector (b);
1893 return value.HasValue ? a + value.Value : a;
1897 public static float Sum (this IEnumerable<float> source)
1899 Check.Source (source);
1901 return Sum<float, float> (source, (a, b) => a + b);
1904 public static float? Sum (this IEnumerable<float?> source)
1906 Check.Source (source);
1908 return SumNullable<float?, float?> (source, (a, b) => a.HasValue ? a + b : a);
1911 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1913 Check.SourceAndSelector (source, selector);
1915 return Sum<TSource, float> (source, (a, b) => a + selector (b));
1918 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1920 Check.SourceAndSelector (source, selector);
1922 return SumNullable<TSource, float?> (source, (a, b) => {
1923 var value = selector (b);
1924 return value.HasValue ? a + value.Value : a;
1928 public static decimal Sum (this IEnumerable<decimal> source)
1930 Check.Source (source);
1932 return Sum<decimal, decimal> (source, (a, b) => a + b);
1935 public static decimal? Sum (this IEnumerable<decimal?> source)
1937 Check.Source (source);
1939 return SumNullable<decimal?, decimal?> (source, (a, b) => a.HasValue ? a + b : a);
1942 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1944 Check.SourceAndSelector (source, selector);
1946 return Sum<TSource, decimal> (source, (a, b) => a + selector (b));
1949 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1951 Check.SourceAndSelector (source, selector);
1953 return SumNullable<TSource, decimal?> (source, (a, b) => {
1954 var value = selector (b);
1955 return value.HasValue ? a + value.Value : a;
1959 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1961 TR total = default (TR);
1963 foreach (var element in source) {
1964 total = selector (total, element);
1969 throw new InvalidOperationException ();
1974 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1976 TR total = default (TR);
1977 foreach (var element in source) {
1978 total = selector (total, element);
1988 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
1990 Check.Source (source);
1992 return CreateTakeIterator (source, count);
1995 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2001 foreach (TSource element in source) {
2002 if (counter++ == count)
2005 yield return element;
2013 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2015 Check.SourceAndPredicate (source, predicate);
2017 return CreateTakeWhileIterator (source, predicate);
2020 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2022 foreach (var element in source) {
2023 if (!predicate (element))
2026 yield return element;
2030 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2032 Check.SourceAndPredicate (source, predicate);
2034 return CreateTakeWhileIterator (source, predicate);
2037 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2040 foreach (var element in source) {
2041 if (!predicate (element, counter))
2044 yield return element;
2053 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2055 return ThenBy<TSource, TKey> (source, keySelector, null);
2058 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2059 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2061 Check.SourceAndKeySelector (source, keySelector);
2063 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2068 #region ThenByDescending
2070 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2071 Func<TSource, TKey> keySelector)
2073 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2076 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2077 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2079 Check.SourceAndKeySelector (source, keySelector);
2081 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2088 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2090 Check.Source (source);
2092 var collection = source as ICollection<TSource>;
2093 if (collection != null) {
2094 var array = new TSource [collection.Count];
2095 collection.CopyTo (array, 0);
2099 return new List<TSource> (source).ToArray ();
2104 #region ToDictionary
2105 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2106 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2108 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2111 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2112 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2114 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2116 if (comparer == null)
2117 comparer = EqualityComparer<TKey>.Default;
2119 var dict = new Dictionary<TKey, TElement> (comparer);
2120 foreach (var e in source)
2121 dict.Add (keySelector (e), elementSelector (e));
2126 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2127 Func<TSource, TKey> keySelector)
2129 return ToDictionary (source, keySelector, null);
2132 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2133 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2135 Check.SourceAndKeySelector (source, keySelector);
2137 if (comparer == null)
2138 comparer = EqualityComparer<TKey>.Default;
2140 var dict = new Dictionary<TKey, TSource> (comparer);
2141 foreach (var e in source)
2142 dict.Add (keySelector (e), e);
2150 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2152 Check.Source (source);
2154 return new List<TSource> (source);
2160 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2162 return ToLookup<TSource, TKey> (source, keySelector, null);
2165 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2166 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2168 Check.SourceAndKeySelector (source, keySelector);
2170 var dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2171 foreach (TSource element in source) {
2172 TKey key = keySelector (element);
2174 throw new ArgumentNullException ();
2175 if (!dictionary.ContainsKey (key))
2176 dictionary.Add (key, new List<TSource> ());
2177 dictionary [key].Add (element);
2179 return new Lookup<TKey, TSource> (dictionary);
2182 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2183 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2185 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2188 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2189 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2191 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2193 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2194 foreach (TSource element in source) {
2195 TKey key = keySelector (element);
2197 throw new ArgumentNullException ();
2198 if (!dictionary.ContainsKey (key))
2199 dictionary.Add (key, new List<TElement> ());
2200 dictionary [key].Add (elementSelector (element));
2202 return new Lookup<TKey, TElement> (dictionary);
2207 #region SequenceEqual
2209 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2211 return first.SequenceEqual (second, null);
2214 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2216 Check.FirstAndSecond (first, second);
2218 if (comparer == null)
2219 comparer = EqualityComparer<TSource>.Default;
2221 var first_enumerator = first.GetEnumerator ();
2222 var second_enumerator = second.GetEnumerator ();
2224 while (first_enumerator.MoveNext ()) {
2225 if (!second_enumerator.MoveNext ())
2228 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2232 return !second_enumerator.MoveNext ();
2239 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2241 Check.FirstAndSecond (first, second);
2243 return first.Union (second, null);
2246 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2248 Check.FirstAndSecond (first, second);
2250 if (comparer == null)
2251 comparer = EqualityComparer<TSource>.Default;
2253 return CreateUnionIterator (first, second, comparer);
2256 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2258 var items = new HashSet<TSource> (comparer);
2259 foreach (var element in first) {
2260 if (! items.Contains (element)) {
2261 items.Add (element);
2262 yield return element;
2266 foreach (var element in second) {
2267 if (! items.Contains (element, comparer)) {
2268 items.Add (element);
2269 yield return element;
2278 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2280 Check.SourceAndPredicate (source, predicate);
2282 return CreateWhereIterator (source, predicate);
2285 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2287 foreach (TSource element in source)
2288 if (predicate (element))
2289 yield return element;
2292 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2294 Check.SourceAndPredicate (source, predicate);
2296 return CreateWhereIterator (source, predicate);
2299 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2302 foreach (TSource element in source) {
2303 if (predicate (element, counter))
2304 yield return element;
2311 class ReadOnlyCollectionOf<T> {
2312 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2315 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2318 return ReadOnlyCollectionOf<TSource>.Empty;
2320 var ro = source as ReadOnlyCollection<TSource>;
2324 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());