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);
731 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
732 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
733 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
734 IEqualityComparer<TKey> comparer)
736 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
737 source, keySelector, elementSelector, comparer);
739 foreach (IGrouping<TKey, TElement> group in groups)
740 yield return resultSelector (group.Key, group);
743 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
744 Func<TSource, TKey> keySelector,
745 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
747 return GroupBy (source, keySelector, resultSelector, null);
751 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
752 Func<TSource, TKey> keySelector,
753 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
754 IEqualityComparer<TKey> comparer)
756 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
758 foreach (IGrouping<TKey, TSource> group in groups)
759 yield return resultSelector (group.Key, group);
766 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
767 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
768 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
770 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
773 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
774 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
775 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
776 IEqualityComparer<TKey> comparer)
778 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
780 if (comparer == null)
781 comparer = EqualityComparer<TKey>.Default;
783 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
784 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
785 foreach (U element in inner)
787 K innerKey = innerKeySelector (element);
788 if (!innerKeys.ContainsKey (innerKey))
789 innerKeys.Add (innerKey, new List<U> ());
790 innerKeys[innerKey].Add (element);
793 foreach (TOuter element in outer) {
794 TKey outerKey = outerKeySelector (element);
795 if (innerKeys.Contains (outerKey))
796 yield return resultSelector (element, innerKeys [outerKey]);
798 yield return resultSelector (element, Empty<TInner> ());
806 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
808 return Intersect (first, second, null);
811 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
813 Check.FirstAndSecond (first, second);
815 if (comparer == null)
816 comparer = EqualityComparer<TSource>.Default;
818 return CreateIntersectIterator (first, second, comparer);
821 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
823 var items = new HashSet<TSource> (second, comparer);
824 foreach (TSource element in first) {
825 if (items.Contains (element))
826 yield return element;
834 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
835 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
836 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
838 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
840 if (comparer == null)
841 comparer = EqualityComparer<TKey>.Default;
843 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
844 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
845 foreach (U element in inner)
847 K innerKey = innerKeySelector (element);
848 if (!innerKeys.ContainsKey (innerKey))
849 innerKeys.Add (innerKey, new List<U> ());
850 innerKeys[innerKey].Add (element);
853 foreach (TOuter element in outer) {
854 TKey outerKey = outerKeySelector (element);
855 if (innerKeys.Contains (outerKey)) {
856 foreach (TInner innerElement in innerKeys [outerKey])
857 yield return resultSelector (element, innerElement);
862 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
863 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
864 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
866 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
873 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
876 var item = default (TSource);
878 foreach (var element in source) {
879 if (!predicate (element))
889 if (fallback == Fallback.Throw)
890 throw new InvalidOperationException ();
895 public static TSource Last<TSource> (this IEnumerable<TSource> source)
897 Check.Source (source);
899 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
902 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
904 Check.SourceAndPredicate (source, predicate);
906 return source.Last (predicate, Fallback.Throw);
911 #region LastOrDefault
913 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
915 Check.Source (source);
917 var list = source as IList<TSource>;
919 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
921 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
924 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
926 Check.SourceAndPredicate (source, predicate);
928 return source.Last (predicate, Fallback.Default);
935 public static long LongCount<TSource> (this IEnumerable<TSource> source)
937 Check.Source (source);
940 var array = source as TSource [];
942 return array.LongLength;
946 using (var enumerator = source.GetEnumerator ())
947 while (enumerator.MoveNext ())
953 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
955 Check.SourceAndSelector (source, selector);
958 foreach (TSource element in source)
959 if (selector (element))
969 public static int Max (this IEnumerable<int> source)
971 Check.Source (source);
973 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
976 public static long Max (this IEnumerable<long> source)
978 Check.Source (source);
980 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
983 public static double Max (this IEnumerable<double> source)
985 Check.Source (source);
987 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
990 public static float Max (this IEnumerable<float> source)
992 Check.Source (source);
994 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
997 public static decimal Max (this IEnumerable<decimal> source)
999 Check.Source (source);
1001 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1004 public static int? Max (this IEnumerable<int?> source)
1006 Check.Source (source);
1008 return IterateNullable (source, int.MinValue, (a, b) => a > b);
1011 public static long? Max (this IEnumerable<long?> source)
1013 Check.Source (source);
1015 return IterateNullable (source, long.MinValue, (a, b) => a > b);
1018 public static double? Max (this IEnumerable<double?> source)
1020 Check.Source (source);
1022 return IterateNullable (source, double.MinValue, (a, b) => a > b);
1025 public static float? Max (this IEnumerable<float?> source)
1027 Check.Source (source);
1029 return IterateNullable (source, float.MinValue, (a, b) => a > b);
1032 public static decimal? Max (this IEnumerable<decimal?> source)
1034 Check.Source (source);
1036 return IterateNullable (source, decimal.MinValue, (a, b) => a > b);
1039 static T? IterateNullable<T> (IEnumerable<T?> source, T initValue, Func<T?, T?, bool> selector) where T : struct
1042 T? value = initValue;
1043 foreach (var element in source) {
1044 if (!element.HasValue)
1047 if (selector (element.Value, value))
1058 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1060 Check.Source (source);
1062 bool notAssigned = true;
1063 TSource maximum = default (TSource);
1065 foreach (TSource element in source) {
1068 notAssigned = false;
1071 if (element is IComparable<TSource>)
1072 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1073 else if (element is System.IComparable)
1074 comparison = ((System.IComparable) element).CompareTo (maximum);
1076 throw new ArgumentNullException ();
1085 throw new InvalidOperationException ();
1090 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1092 Check.SourceAndSelector (source, selector);
1094 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1097 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1099 Check.SourceAndSelector (source, selector);
1101 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1104 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1106 Check.SourceAndSelector (source, selector);
1108 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1111 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1113 Check.SourceAndSelector (source, selector);
1115 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1118 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1120 Check.SourceAndSelector (source, selector);
1122 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1125 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1128 foreach (var element in source) {
1129 initValue = selector (element, initValue);
1134 throw new InvalidOperationException ();
1139 static U? IterateNullable<T, U> (IEnumerable<T> source, U initialValue, Func<T, U?, U?> selector) where U : struct
1142 U? value = initialValue;
1143 foreach (var element in source) {
1144 value = selector (element, value);
1145 if (!value.HasValue)
1157 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1159 Check.SourceAndSelector (source, selector);
1161 return IterateNullable (source, int.MinValue, (a, b) => {
1162 var v = selector (a); return v > b ? v : b;
1166 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1168 Check.SourceAndSelector (source, selector);
1170 return IterateNullable (source, long.MinValue, (a, b) => {
1171 var v = selector (a); return v > b ? v : b;
1175 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1177 Check.SourceAndSelector (source, selector);
1179 return IterateNullable (source, double.MinValue, (a, b) => {
1180 var v = selector (a); return v > b ? v : b;
1184 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1186 Check.SourceAndSelector (source, selector);
1188 return IterateNullable (source, float.MinValue, (a, b) => {
1189 var v = selector (a); return v > b ? v : b;
1193 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1195 Check.SourceAndSelector (source, selector);
1197 return IterateNullable (source, decimal.MinValue, (a, b) => {
1198 var v = selector (a); return v > b ? v : b;
1202 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1204 Check.SourceAndSelector (source, selector);
1206 bool notAssigned = true;
1207 TResult maximum = default (TResult);
1209 foreach (TSource item in source) {
1210 TResult element = selector (item);
1213 notAssigned = false;
1216 if (element is IComparable<TResult>)
1217 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1218 else if (element is System.IComparable)
1219 comparison = ((System.IComparable) element).CompareTo (maximum);
1221 throw new ArgumentNullException ();
1230 throw new InvalidOperationException ();
1239 public static int Min (this IEnumerable<int> source)
1241 Check.Source (source);
1243 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1246 public static long Min (this IEnumerable<long> source)
1248 Check.Source (source);
1250 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1253 public static double Min (this IEnumerable<double> source)
1255 Check.Source (source);
1257 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1260 public static float Min (this IEnumerable<float> source)
1262 Check.Source (source);
1264 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1267 public static decimal Min (this IEnumerable<decimal> source)
1269 Check.Source (source);
1271 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1274 public static int? Min (this IEnumerable<int?> source)
1276 Check.Source (source);
1278 return IterateNullable (source, int.MaxValue, (a, b) => a < b);
1281 public static long? Min (this IEnumerable<long?> source)
1283 Check.Source (source);
1285 return IterateNullable (source, long.MaxValue, (a, b) => a < b);
1288 public static double? Min (this IEnumerable<double?> source)
1290 Check.Source (source);
1292 return IterateNullable (source, double.MaxValue, (a, b) => a < b);
1295 public static float? Min (this IEnumerable<float?> source)
1297 Check.Source (source);
1299 return IterateNullable (source, float.MaxValue, (a, b) => a < b);
1302 public static decimal? Min (this IEnumerable<decimal?> source)
1304 Check.Source (source);
1306 return IterateNullable (source, decimal.MaxValue, (a, b) => a < b);
1309 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1311 Check.Source (source);
1313 bool notAssigned = true;
1314 TSource minimum = default (TSource);
1316 foreach (TSource element in source) {
1319 notAssigned = false;
1322 if (element is IComparable<TSource>)
1323 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1324 else if (element is System.IComparable)
1325 comparison = ((System.IComparable) element).CompareTo (minimum);
1327 throw new ArgumentNullException ();
1336 throw new InvalidOperationException ();
1341 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1343 Check.SourceAndSelector (source, selector);
1345 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1348 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1350 Check.SourceAndSelector (source, selector);
1352 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1355 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1357 Check.SourceAndSelector (source, selector);
1359 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1362 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1364 Check.SourceAndSelector (source, selector);
1366 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1369 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1371 Check.SourceAndSelector (source, selector);
1373 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1376 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1378 Check.SourceAndSelector (source, selector);
1380 return IterateNullable (source, int.MaxValue, (a, b) => {
1381 var v = selector (a); return v < b ? v : b;
1385 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1387 Check.SourceAndSelector (source, selector);
1389 return IterateNullable (source, long.MaxValue, (a, b) => {
1390 var v = selector (a); return v < b ? v : b;
1394 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1396 Check.SourceAndSelector (source, selector);
1398 return IterateNullable (source, float.MaxValue, (a, b) => {
1399 var v = selector (a); return v < b ? v : b;
1403 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1405 Check.SourceAndSelector (source, selector);
1407 return IterateNullable (source, double.MaxValue, (a, b) => {
1408 var v = selector (a); return v < b ? v : b;
1412 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1414 Check.SourceAndSelector (source, selector);
1416 return IterateNullable (source, decimal.MaxValue, (a, b) => {
1417 var v = selector (a); return v < b ? v : b;
1421 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1423 Check.SourceAndSelector (source, selector);
1425 bool notAssigned = true;
1426 TResult minimum = default (TResult);
1428 foreach (TSource item in source) {
1429 TResult element = selector (item);
1432 notAssigned = false;
1435 if (element is IComparable<TResult>)
1436 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1437 else if (element is System.IComparable)
1438 comparison = ((System.IComparable) element).CompareTo (minimum);
1440 throw new ArgumentNullException ();
1449 throw new InvalidOperationException ();
1458 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1460 Check.Source (source);
1462 return CreateOfTypeIterator<TResult> (source);
1465 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1467 foreach (object element in source)
1468 if (element is TResult)
1469 yield return (TResult) element;
1476 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1477 Func<TSource, TKey> keySelector)
1479 return OrderBy<TSource, TKey> (source, keySelector, null);
1482 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1483 Func<TSource, TKey> keySelector,
1484 IComparer<TKey> comparer)
1486 Check.SourceAndKeySelector (source, keySelector);
1488 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1493 #region OrderByDescending
1495 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1496 Func<TSource, TKey> keySelector)
1498 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1501 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1502 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1504 Check.SourceAndKeySelector (source, keySelector);
1506 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1513 public static IEnumerable<int> Range (int start, int count)
1516 throw new ArgumentOutOfRangeException ("count");
1518 long upto = ((long) start + count) - 1;
1520 if (upto > int.MaxValue)
1521 throw new ArgumentOutOfRangeException ();
1523 return CreateRangeIterator (start, (int) upto);
1526 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1528 for (int i = start; i <= upto; i++)
1536 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1539 throw new ArgumentOutOfRangeException ();
1541 return CreateRepeatIterator (element, count);
1544 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1546 for (int i = 0; i < count; i++)
1547 yield return element;
1554 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1556 Check.Source (source);
1558 var list = source as IList<TSource>;
1560 list = new List<TSource> (source);
1562 return CreateReverseIterator (list);
1565 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1567 for (int i = source.Count; i > 0; --i)
1568 yield return source [i - 1];
1575 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1577 Check.SourceAndSelector (source, selector);
1579 return CreateSelectIterator (source, selector);
1582 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1584 foreach (var element in source)
1585 yield return selector (element);
1588 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1590 Check.SourceAndSelector (source, selector);
1592 return CreateSelectIterator (source, selector);
1595 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1598 foreach (TSource element in source) {
1599 yield return selector (element, counter);
1608 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1610 Check.SourceAndSelector (source, selector);
1612 return CreateSelectManyIterator (source, selector);
1615 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1617 foreach (TSource element in source)
1618 foreach (TResult item in selector (element))
1622 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1624 Check.SourceAndSelector (source, selector);
1626 return CreateSelectManyIterator (source, selector);
1629 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1632 foreach (TSource element in source) {
1633 foreach (TResult item in selector (element, counter))
1639 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1640 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1642 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1644 return CreateSelectManyIterator (source, collectionSelector, selector);
1647 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1648 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1650 foreach (TSource element in source)
1651 foreach (TCollection collection in collectionSelector (element))
1652 yield return selector (element, collection);
1655 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1656 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1658 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1660 return CreateSelectManyIterator (source, collectionSelector, selector);
1663 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1664 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1667 foreach (TSource element in source)
1668 foreach (TCollection collection in collectionSelector (element, counter++))
1669 yield return selector (element, collection);
1676 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1679 var item = default (TSource);
1681 foreach (var element in source) {
1682 if (!predicate (element))
1686 throw new InvalidOperationException ();
1692 if (!found && fallback == Fallback.Throw)
1693 throw new InvalidOperationException ();
1698 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1700 Check.Source (source);
1702 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1705 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1707 Check.SourceAndPredicate (source, predicate);
1709 return source.Single (predicate, Fallback.Throw);
1714 #region SingleOrDefault
1716 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1718 Check.Source (source);
1720 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1723 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1725 Check.SourceAndPredicate (source, predicate);
1727 return source.Single (predicate, Fallback.Default);
1734 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1736 Check.Source (source);
1738 return CreateSkipIterator (source, count);
1741 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1744 foreach (var element in source) {
1748 yield return element;
1756 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1758 Check.SourceAndPredicate (source, predicate);
1760 return CreateSkipWhileIterator (source, predicate);
1763 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1767 foreach (TSource element in source) {
1769 yield return element;
1771 if (!predicate (element)) {
1772 yield return element;
1778 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1780 Check.SourceAndPredicate (source, predicate);
1782 return CreateSkipWhileIterator (source, predicate);
1785 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1790 foreach (TSource element in source) {
1792 yield return element;
1794 if (!predicate (element, counter)) {
1795 yield return element;
1806 public static int Sum (this IEnumerable<int> source)
1808 Check.Source (source);
1810 return Sum<int, int> (source, (a, b) => a + b);
1813 public static int? Sum (this IEnumerable<int?> source)
1815 Check.Source (source);
1817 return SumNullable<int?, int?> (source, (a, b) => a.HasValue ? a + b : a);
1820 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1822 Check.SourceAndSelector (source, selector);
1824 return Sum<TSource, int> (source, (a, b) => a + selector (b));
1827 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1829 Check.SourceAndSelector (source, selector);
1831 return SumNullable<TSource, int?> (source, (a, b) => {
1832 var value = selector (b);
1833 return value.HasValue ? a + value.Value : a;
1837 public static long Sum (this IEnumerable<long> source)
1839 Check.Source (source);
1841 return Sum<long, long> (source, (a, b) => a + b);
1844 public static long? Sum (this IEnumerable<long?> source)
1846 Check.Source (source);
1848 return SumNullable<long?, long?> (source, (a, b) => a.HasValue ? a + b : a);
1851 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1853 Check.SourceAndSelector (source, selector);
1855 return Sum<TSource, long> (source, (a, b) => a + selector (b));
1858 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1860 Check.SourceAndSelector (source, selector);
1862 return SumNullable<TSource, long?> (source, (a, b) => {
1863 var value = selector (b);
1864 return value.HasValue ? a + value.Value : a;
1868 public static double Sum (this IEnumerable<double> source)
1870 Check.Source (source);
1872 return Sum<double, double> (source, (a, b) => a + b);
1875 public static double? Sum (this IEnumerable<double?> source)
1877 Check.Source (source);
1879 return SumNullable<double?, double?> (source, (a, b) => a.HasValue ? a + b : a);
1882 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1884 Check.SourceAndSelector (source, selector);
1886 return Sum<TSource, double> (source, (a, b) => a + selector (b));
1889 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1891 Check.SourceAndSelector (source, selector);
1893 return SumNullable<TSource, double?> (source, (a, b) => {
1894 var value = selector (b);
1895 return value.HasValue ? a + value.Value : a;
1899 public static float Sum (this IEnumerable<float> source)
1901 Check.Source (source);
1903 return Sum<float, float> (source, (a, b) => a + b);
1906 public static float? Sum (this IEnumerable<float?> source)
1908 Check.Source (source);
1910 return SumNullable<float?, float?> (source, (a, b) => a.HasValue ? a + b : a);
1913 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1915 Check.SourceAndSelector (source, selector);
1917 return Sum<TSource, float> (source, (a, b) => a + selector (b));
1920 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1922 Check.SourceAndSelector (source, selector);
1924 return SumNullable<TSource, float?> (source, (a, b) => {
1925 var value = selector (b);
1926 return value.HasValue ? a + value.Value : a;
1930 public static decimal Sum (this IEnumerable<decimal> source)
1932 Check.Source (source);
1934 return Sum<decimal, decimal> (source, (a, b) => a + b);
1937 public static decimal? Sum (this IEnumerable<decimal?> source)
1939 Check.Source (source);
1941 return SumNullable<decimal?, decimal?> (source, (a, b) => a.HasValue ? a + b : a);
1944 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1946 Check.SourceAndSelector (source, selector);
1948 return Sum<TSource, decimal> (source, (a, b) => a + selector (b));
1951 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1953 Check.SourceAndSelector (source, selector);
1955 return SumNullable<TSource, decimal?> (source, (a, b) => {
1956 var value = selector (b);
1957 return value.HasValue ? a + value.Value : a;
1961 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1963 TR total = default (TR);
1965 foreach (var element in source) {
1966 total = selector (total, element);
1971 throw new InvalidOperationException ();
1976 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1978 TR total = default (TR);
1979 foreach (var element in source) {
1980 total = selector (total, element);
1990 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
1992 Check.Source (source);
1994 return CreateTakeIterator (source, count);
1997 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2003 foreach (TSource element in source) {
2004 if (counter++ == count)
2007 yield return element;
2015 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2017 Check.SourceAndPredicate (source, predicate);
2019 return CreateTakeWhileIterator (source, predicate);
2022 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2024 foreach (var element in source) {
2025 if (!predicate (element))
2028 yield return element;
2032 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2034 Check.SourceAndPredicate (source, predicate);
2036 return CreateTakeWhileIterator (source, predicate);
2039 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2042 foreach (var element in source) {
2043 if (!predicate (element, counter))
2046 yield return element;
2055 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2057 return ThenBy<TSource, TKey> (source, keySelector, null);
2060 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2061 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2063 Check.SourceAndKeySelector (source, keySelector);
2065 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2070 #region ThenByDescending
2072 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2073 Func<TSource, TKey> keySelector)
2075 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2078 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2079 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2081 Check.SourceAndKeySelector (source, keySelector);
2083 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2090 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2092 Check.Source (source);
2094 var collection = source as ICollection<TSource>;
2095 if (collection != null) {
2096 var array = new TSource [collection.Count];
2097 collection.CopyTo (array, 0);
2101 return new List<TSource> (source).ToArray ();
2106 #region ToDictionary
2107 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2108 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2110 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2113 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2114 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2116 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2118 if (comparer == null)
2119 comparer = EqualityComparer<TKey>.Default;
2121 var dict = new Dictionary<TKey, TElement> (comparer);
2122 foreach (var e in source)
2123 dict.Add (keySelector (e), elementSelector (e));
2128 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2129 Func<TSource, TKey> keySelector)
2131 return ToDictionary (source, keySelector, null);
2134 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2135 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2137 Check.SourceAndKeySelector (source, keySelector);
2139 if (comparer == null)
2140 comparer = EqualityComparer<TKey>.Default;
2142 var dict = new Dictionary<TKey, TSource> (comparer);
2143 foreach (var e in source)
2144 dict.Add (keySelector (e), e);
2152 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2154 Check.Source (source);
2156 return new List<TSource> (source);
2162 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2164 return ToLookup<TSource, TKey> (source, keySelector, null);
2167 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2168 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2170 Check.SourceAndKeySelector (source, keySelector);
2172 var dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2173 foreach (TSource element in source) {
2174 TKey key = keySelector (element);
2176 throw new ArgumentNullException ();
2177 if (!dictionary.ContainsKey (key))
2178 dictionary.Add (key, new List<TSource> ());
2179 dictionary [key].Add (element);
2181 return new Lookup<TKey, TSource> (dictionary);
2184 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2185 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2187 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2190 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2191 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2193 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2195 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2196 foreach (TSource element in source) {
2197 TKey key = keySelector (element);
2199 throw new ArgumentNullException ();
2200 if (!dictionary.ContainsKey (key))
2201 dictionary.Add (key, new List<TElement> ());
2202 dictionary [key].Add (elementSelector (element));
2204 return new Lookup<TKey, TElement> (dictionary);
2209 #region SequenceEqual
2211 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2213 return first.SequenceEqual (second, null);
2216 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2218 Check.FirstAndSecond (first, second);
2220 if (comparer == null)
2221 comparer = EqualityComparer<TSource>.Default;
2223 var first_enumerator = first.GetEnumerator ();
2224 var second_enumerator = second.GetEnumerator ();
2226 while (first_enumerator.MoveNext ()) {
2227 if (!second_enumerator.MoveNext ())
2230 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2234 return !second_enumerator.MoveNext ();
2241 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2243 Check.FirstAndSecond (first, second);
2245 return first.Union (second, null);
2248 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2250 Check.FirstAndSecond (first, second);
2252 if (comparer == null)
2253 comparer = EqualityComparer<TSource>.Default;
2255 return CreateUnionIterator (first, second, comparer);
2258 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2260 var items = new HashSet<TSource> (comparer);
2261 foreach (var element in first) {
2262 if (! items.Contains (element)) {
2263 items.Add (element);
2264 yield return element;
2268 foreach (var element in second) {
2269 if (! items.Contains (element, comparer)) {
2270 items.Add (element);
2271 yield return element;
2280 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2282 Check.SourceAndPredicate (source, predicate);
2284 return CreateWhereIterator (source, predicate);
2287 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2289 foreach (TSource element in source)
2290 if (predicate (element))
2291 yield return element;
2294 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2296 Check.SourceAndPredicate (source, predicate);
2298 return CreateWhereIterator (source, predicate);
2301 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2304 foreach (TSource element in source) {
2305 if (predicate (element, counter))
2306 yield return element;
2313 class ReadOnlyCollectionOf<T> {
2314 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2317 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2320 return ReadOnlyCollectionOf<TSource>.Empty;
2322 var ro = source as ReadOnlyCollection<TSource>;
2326 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());