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;
53 public static readonly Func<T, T> Identity = (t) => t;
58 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
60 Check.SourceAndFunc (source, func);
62 // custom foreach so that we can efficiently throw an exception
63 // if zero elements and treat the first element differently
64 using (var enumerator = source.GetEnumerator ()) {
65 if (!enumerator.MoveNext ())
66 throw new InvalidOperationException ("No elements in source list");
68 TSource folded = enumerator.Current;
69 while (enumerator.MoveNext ())
70 folded = func (folded, enumerator.Current);
75 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
76 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
78 Check.SourceAndFunc (source, func);
80 TAccumulate folded = seed;
81 foreach (TSource element in source)
82 folded = func (folded, element);
87 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
89 Check.SourceAndFunc (source, func);
90 if (resultSelector == null)
91 throw new ArgumentNullException ("resultSelector");
94 foreach (var e in source)
95 result = func (result, e);
97 return resultSelector (result);
104 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
106 Check.SourceAndPredicate (source, predicate);
108 foreach (var element in source)
109 if (!predicate (element))
119 public static bool Any<TSource> (this IEnumerable<TSource> source)
121 Check.Source (source);
123 var collection = source as ICollection<TSource>;
124 if (collection != null)
125 return collection.Count > 0;
127 using (var enumerator = source.GetEnumerator ())
128 return enumerator.MoveNext ();
131 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
133 Check.SourceAndPredicate (source, predicate);
135 foreach (TSource element in source)
136 if (predicate (element))
146 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
155 public static double Average (this IEnumerable<int> source)
157 return Average<int, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
160 public static double Average (this IEnumerable<long> source)
162 return Average<long, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
165 public static double Average (this IEnumerable<double> source)
167 return Average<double, double, double> (source, (a, b) => a + b, (a, b) => a / b);
170 public static float Average (this IEnumerable<float> source)
172 return Average<float, double, float> (source, (a, b) => a + b, (a, b) => (float) a / (float) b);
175 public static decimal Average (this IEnumerable<decimal> source)
177 return Average<decimal, decimal, decimal> (source, (a, b) => a + b, (a, b) => a / b);
180 static TResult Average<TElement, TAggregate, TResult> (this IEnumerable<TElement> source,
181 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
182 where TElement : struct
183 where TAggregate : struct
184 where TResult : struct
186 Check.Source (source);
188 var total = default (TAggregate);
190 foreach (var element in source) {
191 total = func (total, element);
196 throw new InvalidOperationException ();
198 return result (total, counter);
201 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
202 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
203 where TElement : struct
204 where TAggregate : struct
205 where TResult : struct
207 Check.Source (source);
209 var total = default (TAggregate);
211 foreach (var element in source) {
212 if (!element.HasValue)
215 total = func (total, element.Value);
222 return new TResult? (result (total, counter));
225 public static double? Average (this IEnumerable<int?> source)
227 Check.Source (source);
229 return source.AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
232 public static double? Average (this IEnumerable<long?> source)
234 Check.Source (source);
236 return source.AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / b);
239 public static double? Average (this IEnumerable<double?> source)
241 Check.Source (source);
243 return source.AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
246 public static decimal? Average (this IEnumerable<decimal?> source)
248 Check.Source (source);
250 return source.AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
253 public static float? Average (this IEnumerable<float?> source)
255 Check.Source (source);
257 return source.AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
260 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
262 Check.SourceAndSelector (source, selector);
264 return source.Select (selector).Average<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
267 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
269 Check.SourceAndSelector (source, selector);
271 return source.Select (selector).AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
274 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
276 Check.SourceAndSelector (source, selector);
278 return source.Select (selector).Average<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
281 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
283 Check.SourceAndSelector (source, selector);
285 return source.Select (selector).AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
288 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
290 Check.SourceAndSelector (source, selector);
292 return source.Select (selector).Average<double, double, double> ((a, b) => a + b, (a, b) => a / b);
295 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
297 Check.SourceAndSelector (source, selector);
299 return source.Select (selector).AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
302 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
304 Check.SourceAndSelector (source, selector);
306 return source.Select (selector).Average<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
309 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
311 Check.SourceAndSelector (source, selector);
313 return source.Select (selector).AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
316 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
318 Check.SourceAndSelector (source, selector);
320 return source.Select (selector).Average<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
323 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
325 Check.SourceAndSelector (source, selector);
327 return source.Select (selector).AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
334 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
336 Check.Source (source);
338 return CreateCastIterator<TResult> (source);
341 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
343 foreach (TResult element in source)
344 yield return element;
351 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
353 Check.FirstAndSecond (first, second);
355 return CreateConcatIterator (first, second);
358 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
360 foreach (TSource element in first)
361 yield return element;
362 foreach (TSource element in second)
363 yield return element;
370 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
372 var collection = source as ICollection<TSource>;
373 if (collection != null)
374 return collection.Contains (value);
376 return Contains<TSource> (source, value, null);
379 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
381 Check.Source (source);
383 if (comparer == null)
384 comparer = EqualityComparer<TSource>.Default;
386 foreach (var element in source)
387 if (comparer.Equals (element, value))
396 public static int Count<TSource> (this IEnumerable<TSource> source)
398 Check.Source (source);
400 var collection = source as ICollection<TSource>;
401 if (collection != null)
402 return collection.Count;
405 using (var enumerator = source.GetEnumerator ())
406 while (enumerator.MoveNext ())
412 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
414 Check.SourceAndSelector (source, selector);
417 foreach (var element in source)
418 if (selector (element))
426 #region DefaultIfEmpty
428 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
430 return DefaultIfEmpty (source, default (TSource));
433 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
435 Check.Source (source);
437 return CreateDefaultIfEmptyIterator (source, defaultValue);
440 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
443 foreach (TSource item in source) {
449 yield return defaultValue;
456 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
458 return Distinct<TSource> (source, null);
461 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
463 Check.Source (source);
465 if (comparer == null)
466 comparer = EqualityComparer<TSource>.Default;
468 return CreateDistinctIterator (source, comparer);
471 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
473 var items = new HashSet<TSource> (comparer);
474 foreach (var element in source) {
475 if (! items.Contains (element)) {
477 yield return element;
486 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
490 foreach (var element in source) {
491 if (index == counter++)
495 if (fallback == Fallback.Throw)
496 throw new ArgumentOutOfRangeException ();
498 return default (TSource);
501 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
503 Check.Source (source);
506 throw new ArgumentOutOfRangeException ();
508 var list = source as IList<TSource>;
512 return source.ElementAt (index, Fallback.Throw);
517 #region ElementAtOrDefault
519 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
521 Check.Source (source);
524 return default (TSource);
526 var list = source as IList<TSource>;
528 return index < list.Count ? list [index] : default (TSource);
530 return source.ElementAt (index, Fallback.Default);
537 public static IEnumerable<TResult> Empty<TResult> ()
539 return new TResult [0];
546 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
548 return Except (first, second, null);
551 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
553 Check.FirstAndSecond (first, second);
555 if (comparer == null)
556 comparer = EqualityComparer<TSource>.Default;
558 return CreateExceptIterator (first, second, comparer);
561 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
563 var items = new HashSet<TSource> (second, comparer);
564 foreach (var element in first) {
565 if (!items.Contains (element, comparer))
566 yield return element;
574 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
576 foreach (var element in source)
577 if (predicate (element))
580 if (fallback == Fallback.Throw)
581 throw new InvalidOperationException ();
583 return default (TSource);
586 public static TSource First<TSource> (this IEnumerable<TSource> source)
588 Check.Source (source);
590 var list = source as IList<TSource>;
595 throw new InvalidOperationException ();
597 using (var enumerator = source.GetEnumerator ()) {
598 if (enumerator.MoveNext ())
599 return enumerator.Current;
603 throw new InvalidOperationException ();
606 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
608 Check.SourceAndPredicate (source, predicate);
610 return source.First (predicate, Fallback.Throw);
615 #region FirstOrDefault
617 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
619 Check.Source (source);
621 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
624 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
626 Check.SourceAndPredicate (source, predicate);
628 return source.First (predicate, Fallback.Default);
635 private static List<T> ContainsGroup<K, T> (
636 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
638 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
639 foreach (KeyValuePair<K, List<T>> value in items) {
640 if (comparerInUse.Equals (value.Key, key))
646 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
647 Func<TSource, TKey> keySelector)
649 return GroupBy<TSource, TKey> (source, keySelector, null);
652 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
653 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
655 Check.SourceAndKeySelector (source, keySelector);
657 return CreateGroupByIterator (source, keySelector, comparer);
660 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
661 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
663 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
664 List<TSource> nullList = new List<TSource> ();
666 int nullCounter = -1;
668 foreach (TSource element in source) {
669 TKey key = keySelector (element);
671 nullList.Add (element);
672 if (nullCounter == -1) {
673 nullCounter = counter;
677 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
679 group = new List<TSource> ();
680 groups.Add (key, group);
688 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
689 if (counter == nullCounter) {
690 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
691 yield return nullGroup;
694 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
695 yield return grouping;
700 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
701 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
703 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
706 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
707 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
709 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
711 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
712 List<TElement> nullList = new List<TElement> ();
714 int nullCounter = -1;
716 foreach (TSource item in source) {
717 TKey key = keySelector (item);
718 TElement element = elementSelector (item);
720 nullList.Add (element);
721 if (nullCounter == -1) {
722 nullCounter = counter;
726 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
728 group = new List<TElement> ();
729 groups.Add (key, group);
737 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
738 if (counter == nullCounter) {
739 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
740 yield return nullGroup;
743 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
744 yield return grouping;
749 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
750 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
751 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
753 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
756 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
757 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
758 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
759 IEqualityComparer<TKey> comparer)
761 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
762 source, keySelector, elementSelector, comparer);
764 foreach (IGrouping<TKey, TElement> group in groups)
765 yield return resultSelector (group.Key, group);
768 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
769 Func<TSource, TKey> keySelector,
770 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
772 return GroupBy (source, keySelector, resultSelector, null);
775 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
776 Func<TSource, TKey> keySelector,
777 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
778 IEqualityComparer<TKey> comparer)
780 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
782 foreach (IGrouping<TKey, TSource> group in groups)
783 yield return resultSelector (group.Key, group);
790 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
791 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
792 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
794 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
797 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
798 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
799 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
800 IEqualityComparer<TKey> comparer)
802 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
804 if (comparer == null)
805 comparer = EqualityComparer<TKey>.Default;
807 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
810 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
811 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
812 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
813 IEqualityComparer<TKey> comparer)
815 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
816 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
817 foreach (U element in inner)
819 K innerKey = innerKeySelector (element);
820 if (!innerKeys.ContainsKey (innerKey))
821 innerKeys.Add (innerKey, new List<U> ());
822 innerKeys[innerKey].Add (element);
825 foreach (TOuter element in outer) {
826 TKey outerKey = outerKeySelector (element);
827 if (innerKeys.Contains (outerKey))
828 yield return resultSelector (element, innerKeys [outerKey]);
830 yield return resultSelector (element, Empty<TInner> ());
838 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
840 return Intersect (first, second, null);
843 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
845 Check.FirstAndSecond (first, second);
847 if (comparer == null)
848 comparer = EqualityComparer<TSource>.Default;
850 return CreateIntersectIterator (first, second, comparer);
853 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
855 var items = new HashSet<TSource> (second, comparer);
856 foreach (TSource element in first) {
857 if (items.Contains (element))
858 yield return element;
866 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
867 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
868 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
870 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
872 if (comparer == null)
873 comparer = EqualityComparer<TKey>.Default;
875 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
878 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
879 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
880 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
882 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
883 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
884 foreach (U element in inner)
886 K innerKey = innerKeySelector (element);
887 if (!innerKeys.ContainsKey (innerKey))
888 innerKeys.Add (innerKey, new List<U> ());
889 innerKeys[innerKey].Add (element);
892 foreach (TOuter element in outer) {
893 TKey outerKey = outerKeySelector (element);
894 if (innerKeys.Contains (outerKey)) {
895 foreach (TInner innerElement in innerKeys [outerKey])
896 yield return resultSelector (element, innerElement);
901 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
902 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
903 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
905 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
912 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
915 var item = default (TSource);
917 foreach (var element in source) {
918 if (!predicate (element))
928 if (fallback == Fallback.Throw)
929 throw new InvalidOperationException ();
934 public static TSource Last<TSource> (this IEnumerable<TSource> source)
936 Check.Source (source);
938 var collection = source as ICollection<TSource>;
939 if (collection != null && collection.Count == 0)
940 throw new InvalidOperationException ();
942 var list = source as IList<TSource>;
944 return list [list.Count - 1];
946 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
949 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
951 Check.SourceAndPredicate (source, predicate);
953 return source.Last (predicate, Fallback.Throw);
958 #region LastOrDefault
960 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
962 Check.Source (source);
964 var list = source as IList<TSource>;
966 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
968 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
971 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
973 Check.SourceAndPredicate (source, predicate);
975 return source.Last (predicate, Fallback.Default);
982 public static long LongCount<TSource> (this IEnumerable<TSource> source)
984 Check.Source (source);
987 var array = source as TSource [];
989 return array.LongLength;
993 using (var enumerator = source.GetEnumerator ())
994 while (enumerator.MoveNext ())
1000 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1002 Check.SourceAndSelector (source, selector);
1005 foreach (TSource element in source)
1006 if (selector (element))
1016 public static int Max (this IEnumerable<int> source)
1018 Check.Source (source);
1020 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
1023 public static long Max (this IEnumerable<long> source)
1025 Check.Source (source);
1027 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
1030 public static double Max (this IEnumerable<double> source)
1032 Check.Source (source);
1034 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
1037 public static float Max (this IEnumerable<float> source)
1039 Check.Source (source);
1041 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
1044 public static decimal Max (this IEnumerable<decimal> source)
1046 Check.Source (source);
1048 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1051 public static int? Max (this IEnumerable<int?> source)
1053 Check.Source (source);
1055 return IterateNullable (source, (a, b) => a > b);
1058 public static long? Max (this IEnumerable<long?> source)
1060 Check.Source (source);
1062 return IterateNullable (source, (a, b) => a > b);
1065 public static double? Max (this IEnumerable<double?> source)
1067 Check.Source (source);
1069 return IterateNullable (source, (a, b) => a > b);
1072 public static float? Max (this IEnumerable<float?> source)
1074 Check.Source (source);
1076 return IterateNullable (source, (a, b) => a > b);
1079 public static decimal? Max (this IEnumerable<decimal?> source)
1081 Check.Source (source);
1083 return IterateNullable (source, (a, b) => a > b);
1086 static T? IterateNullable<T> (IEnumerable<T?> source, Func<T?, T?, bool> selector) where T : struct
1090 foreach (var element in source) {
1091 if (!element.HasValue)
1094 if (!value.HasValue)
1095 value = element.Value;
1096 else if (selector (element.Value, value))
1108 static TRet? IterateNullable<TSource, TRet> (
1109 IEnumerable<TSource> source,
1110 Func<TSource, TRet?> source_selector,
1111 Func<TRet?, TRet?, bool> selector) where TRet : struct
1115 foreach (var element in source) {
1116 TRet? item = source_selector (element);
1118 if (!value.HasValue)
1120 else if (selector (item, value))
1132 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1134 Check.Source (source);
1136 bool notAssigned = true;
1137 TSource maximum = default (TSource);
1139 foreach (TSource element in source) {
1142 notAssigned = false;
1145 if (element is IComparable<TSource>)
1146 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1147 else if (element is System.IComparable)
1148 comparison = ((System.IComparable) element).CompareTo (maximum);
1150 throw new ArgumentNullException ();
1159 throw new InvalidOperationException ();
1164 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1166 Check.SourceAndSelector (source, selector);
1168 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1171 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1173 Check.SourceAndSelector (source, selector);
1175 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1178 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1180 Check.SourceAndSelector (source, selector);
1182 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1185 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1187 Check.SourceAndSelector (source, selector);
1189 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1192 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1194 Check.SourceAndSelector (source, selector);
1196 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1199 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1202 foreach (var element in source) {
1203 initValue = selector (element, initValue);
1208 throw new InvalidOperationException ();
1213 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1215 Check.SourceAndSelector (source, selector);
1217 return IterateNullable (source, selector, (a, b) => a > b);
1220 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1222 Check.SourceAndSelector (source, selector);
1224 return IterateNullable (source, selector, (a, b) => a > b);
1227 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1229 Check.SourceAndSelector (source, selector);
1231 return IterateNullable (source, selector, (a, b) => a > b);
1234 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1236 Check.SourceAndSelector (source, selector);
1238 return IterateNullable (source, selector, (a, b) => a > b);
1241 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1243 Check.SourceAndSelector (source, selector);
1245 return IterateNullable (source, selector, (a, b) => a > b);
1248 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1250 Check.SourceAndSelector (source, selector);
1252 bool notAssigned = true;
1253 TResult maximum = default (TResult);
1255 foreach (TSource item in source) {
1256 TResult element = selector (item);
1259 notAssigned = false;
1262 if (element is IComparable<TResult>)
1263 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1264 else if (element is System.IComparable)
1265 comparison = ((System.IComparable) element).CompareTo (maximum);
1267 throw new ArgumentNullException ();
1276 throw new InvalidOperationException ();
1285 public static int Min (this IEnumerable<int> source)
1287 Check.Source (source);
1289 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1292 public static long Min (this IEnumerable<long> source)
1294 Check.Source (source);
1296 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1299 public static double Min (this IEnumerable<double> source)
1301 Check.Source (source);
1303 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1306 public static float Min (this IEnumerable<float> source)
1308 Check.Source (source);
1310 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1313 public static decimal Min (this IEnumerable<decimal> source)
1315 Check.Source (source);
1317 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1320 public static int? Min (this IEnumerable<int?> source)
1322 Check.Source (source);
1324 return IterateNullable (source, (a, b) => a < b);
1327 public static long? Min (this IEnumerable<long?> source)
1329 Check.Source (source);
1331 return IterateNullable (source, (a, b) => a < b);
1334 public static double? Min (this IEnumerable<double?> source)
1336 Check.Source (source);
1338 return IterateNullable (source, (a, b) => a < b);
1341 public static float? Min (this IEnumerable<float?> source)
1343 Check.Source (source);
1345 return IterateNullable (source, (a, b) => a < b);
1348 public static decimal? Min (this IEnumerable<decimal?> source)
1350 Check.Source (source);
1352 return IterateNullable (source, (a, b) => a < b);
1355 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1357 Check.Source (source);
1359 bool notAssigned = true;
1360 TSource minimum = default (TSource);
1362 foreach (TSource element in source) {
1365 notAssigned = false;
1368 if (element is IComparable<TSource>)
1369 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1370 else if (element is System.IComparable)
1371 comparison = ((System.IComparable) element).CompareTo (minimum);
1373 throw new ArgumentNullException ();
1382 throw new InvalidOperationException ();
1387 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1389 Check.SourceAndSelector (source, selector);
1391 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1394 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1396 Check.SourceAndSelector (source, selector);
1398 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1401 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1403 Check.SourceAndSelector (source, selector);
1405 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1408 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1410 Check.SourceAndSelector (source, selector);
1412 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1415 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1417 Check.SourceAndSelector (source, selector);
1419 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1422 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1424 Check.SourceAndSelector (source, selector);
1426 return IterateNullable (source, selector, (a, b) => a < b);
1429 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1431 Check.SourceAndSelector (source, selector);
1433 return IterateNullable (source, selector, (a, b) => a < b);
1436 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1438 Check.SourceAndSelector (source, selector);
1440 return IterateNullable (source, selector, (a, b) => a < b);
1443 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1445 Check.SourceAndSelector (source, selector);
1447 return IterateNullable (source, selector, (a, b) => a < b);
1450 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1452 Check.SourceAndSelector (source, selector);
1454 return IterateNullable (source, selector, (a, b) => a < b);
1457 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1459 Check.SourceAndSelector (source, selector);
1461 bool notAssigned = true;
1462 TResult minimum = default (TResult);
1464 foreach (TSource item in source) {
1465 TResult element = selector (item);
1468 notAssigned = false;
1471 if (element is IComparable<TResult>)
1472 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1473 else if (element is System.IComparable)
1474 comparison = ((System.IComparable) element).CompareTo (minimum);
1476 throw new ArgumentNullException ();
1485 throw new InvalidOperationException ();
1494 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1496 Check.Source (source);
1498 return CreateOfTypeIterator<TResult> (source);
1501 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1503 foreach (object element in source)
1504 if (element is TResult)
1505 yield return (TResult) element;
1512 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1513 Func<TSource, TKey> keySelector)
1515 return OrderBy<TSource, TKey> (source, keySelector, null);
1518 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1519 Func<TSource, TKey> keySelector,
1520 IComparer<TKey> comparer)
1522 Check.SourceAndKeySelector (source, keySelector);
1524 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1529 #region OrderByDescending
1531 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1532 Func<TSource, TKey> keySelector)
1534 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1537 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1538 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1540 Check.SourceAndKeySelector (source, keySelector);
1542 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1549 public static IEnumerable<int> Range (int start, int count)
1552 throw new ArgumentOutOfRangeException ("count");
1554 long upto = ((long) start + count) - 1;
1556 if (upto > int.MaxValue)
1557 throw new ArgumentOutOfRangeException ();
1559 return CreateRangeIterator (start, (int) upto);
1562 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1564 for (int i = start; i <= upto; i++)
1572 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1575 throw new ArgumentOutOfRangeException ();
1577 return CreateRepeatIterator (element, count);
1580 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1582 for (int i = 0; i < count; i++)
1583 yield return element;
1590 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1592 Check.Source (source);
1594 var list = source as IList<TSource>;
1596 list = new List<TSource> (source);
1598 return CreateReverseIterator (list);
1601 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1603 for (int i = source.Count; i > 0; --i)
1604 yield return source [i - 1];
1611 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1613 Check.SourceAndSelector (source, selector);
1615 return CreateSelectIterator (source, selector);
1618 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1620 foreach (var element in source)
1621 yield return selector (element);
1624 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1626 Check.SourceAndSelector (source, selector);
1628 return CreateSelectIterator (source, selector);
1631 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1634 foreach (TSource element in source) {
1635 yield return selector (element, counter);
1644 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1646 Check.SourceAndSelector (source, selector);
1648 return CreateSelectManyIterator (source, selector);
1651 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1653 foreach (TSource element in source)
1654 foreach (TResult item in selector (element))
1658 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1660 Check.SourceAndSelector (source, selector);
1662 return CreateSelectManyIterator (source, selector);
1665 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1668 foreach (TSource element in source) {
1669 foreach (TResult item in selector (element, counter))
1675 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1676 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1678 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1680 return CreateSelectManyIterator (source, collectionSelector, selector);
1683 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1684 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1686 foreach (TSource element in source)
1687 foreach (TCollection collection in collectionSelector (element))
1688 yield return selector (element, collection);
1691 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1692 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1694 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1696 return CreateSelectManyIterator (source, collectionSelector, selector);
1699 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1700 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1703 foreach (TSource element in source)
1704 foreach (TCollection collection in collectionSelector (element, counter++))
1705 yield return selector (element, collection);
1712 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1715 var item = default (TSource);
1717 foreach (var element in source) {
1718 if (!predicate (element))
1722 throw new InvalidOperationException ();
1728 if (!found && fallback == Fallback.Throw)
1729 throw new InvalidOperationException ();
1734 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1736 Check.Source (source);
1738 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1741 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1743 Check.SourceAndPredicate (source, predicate);
1745 return source.Single (predicate, Fallback.Throw);
1750 #region SingleOrDefault
1752 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1754 Check.Source (source);
1756 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1759 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1761 Check.SourceAndPredicate (source, predicate);
1763 return source.Single (predicate, Fallback.Default);
1770 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1772 Check.Source (source);
1774 return CreateSkipIterator (source, count);
1777 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1780 foreach (var element in source) {
1784 yield return element;
1792 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1794 Check.SourceAndPredicate (source, predicate);
1796 return CreateSkipWhileIterator (source, predicate);
1799 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1803 foreach (TSource element in source) {
1805 yield return element;
1807 if (!predicate (element)) {
1808 yield return element;
1814 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1816 Check.SourceAndPredicate (source, predicate);
1818 return CreateSkipWhileIterator (source, predicate);
1821 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1826 foreach (TSource element in source) {
1828 yield return element;
1830 if (!predicate (element, counter)) {
1831 yield return element;
1842 public static int Sum (this IEnumerable<int> source)
1844 Check.Source (source);
1846 return Sum<int, int> (source, (a, b) => checked (a + b));
1849 public static int? Sum (this IEnumerable<int?> source)
1851 Check.Source (source);
1853 return source.SumNullable<int?, int?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1856 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1858 Check.SourceAndSelector (source, selector);
1860 return Sum<TSource, int> (source, (a, b) => checked (a + selector (b)));
1863 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1865 Check.SourceAndSelector (source, selector);
1867 return source.SumNullable<TSource, int?> (0, (a, b) => {
1868 var value = selector (b);
1869 return value.HasValue ? checked (a + value.Value) : a;
1873 public static long Sum (this IEnumerable<long> source)
1875 Check.Source (source);
1877 return Sum<long, long> (source, (a, b) => checked (a + b));
1880 public static long? Sum (this IEnumerable<long?> source)
1882 Check.Source (source);
1884 return source.SumNullable<long?, long?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1887 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1889 Check.SourceAndSelector (source, selector);
1891 return Sum<TSource, long> (source, (a, b) => checked (a + selector (b)));
1894 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1896 Check.SourceAndSelector (source, selector);
1898 return source.SumNullable<TSource, long?> (0, (a, b) => {
1899 var value = selector (b);
1900 return value.HasValue ? checked (a + value.Value) : a;
1904 public static double Sum (this IEnumerable<double> source)
1906 Check.Source (source);
1908 return Sum<double, double> (source, (a, b) => checked (a + b));
1911 public static double? Sum (this IEnumerable<double?> source)
1913 Check.Source (source);
1915 return source.SumNullable<double?, double?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1918 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1920 Check.SourceAndSelector (source, selector);
1922 return Sum<TSource, double> (source, (a, b) => checked (a + selector (b)));
1925 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1927 Check.SourceAndSelector (source, selector);
1929 return source.SumNullable<TSource, double?> (0, (a, b) => {
1930 var value = selector (b);
1931 return value.HasValue ? checked (a + value.Value) : a;
1935 public static float Sum (this IEnumerable<float> source)
1937 Check.Source (source);
1939 return Sum<float, float> (source, (a, b) => checked (a + b));
1942 public static float? Sum (this IEnumerable<float?> source)
1944 Check.Source (source);
1946 return source.SumNullable<float?, float?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1949 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1951 Check.SourceAndSelector (source, selector);
1953 return Sum<TSource, float> (source, (a, b) => checked (a + selector (b)));
1956 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1958 Check.SourceAndSelector (source, selector);
1960 return source.SumNullable<TSource, float?> (0, (a, b) => {
1961 var value = selector (b);
1962 return value.HasValue ? checked (a + value.Value) : a;
1966 public static decimal Sum (this IEnumerable<decimal> source)
1968 Check.Source (source);
1970 return Sum<decimal, decimal> (source, (a, b) => checked (a + b));
1973 public static decimal? Sum (this IEnumerable<decimal?> source)
1975 Check.Source (source);
1977 return source.SumNullable<decimal?, decimal?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1980 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1982 Check.SourceAndSelector (source, selector);
1984 return Sum<TSource, decimal> (source, (a, b) => checked (a + selector (b)));
1987 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1989 Check.SourceAndSelector (source, selector);
1991 return source.SumNullable<TSource, decimal?> (0, (a, b) => {
1992 var value = selector (b);
1993 return value.HasValue ? checked (a + value.Value) : a;
1997 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1999 TR total = default (TR);
2001 foreach (var element in source) {
2002 total = selector (total, element);
2009 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, TR zero, Func<TR, TA, TR> selector)
2012 foreach (var element in source) {
2013 total = selector (total, element);
2023 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2025 Check.Source (source);
2027 return CreateTakeIterator (source, count);
2030 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2036 foreach (TSource element in source) {
2037 yield return element;
2039 if (++counter == count)
2048 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2050 Check.SourceAndPredicate (source, predicate);
2052 return CreateTakeWhileIterator (source, predicate);
2055 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2057 foreach (var element in source) {
2058 if (!predicate (element))
2061 yield return element;
2065 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2067 Check.SourceAndPredicate (source, predicate);
2069 return CreateTakeWhileIterator (source, predicate);
2072 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2075 foreach (var element in source) {
2076 if (!predicate (element, counter))
2079 yield return element;
2088 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2090 return ThenBy<TSource, TKey> (source, keySelector, null);
2093 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2094 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2096 Check.SourceAndKeySelector (source, keySelector);
2098 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2103 #region ThenByDescending
2105 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2106 Func<TSource, TKey> keySelector)
2108 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2111 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2112 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2114 Check.SourceAndKeySelector (source, keySelector);
2116 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2123 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2125 Check.Source (source);
2127 var collection = source as ICollection<TSource>;
2128 if (collection != null) {
2129 var array = new TSource [collection.Count];
2130 collection.CopyTo (array, 0);
2134 return new List<TSource> (source).ToArray ();
2139 #region ToDictionary
2140 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2141 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2143 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2146 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2147 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2149 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2151 if (comparer == null)
2152 comparer = EqualityComparer<TKey>.Default;
2154 var dict = new Dictionary<TKey, TElement> (comparer);
2155 foreach (var e in source)
2156 dict.Add (keySelector (e), elementSelector (e));
2161 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2162 Func<TSource, TKey> keySelector)
2164 return ToDictionary (source, keySelector, null);
2167 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2168 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2170 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2176 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2178 Check.Source (source);
2180 return new List<TSource> (source);
2186 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2188 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2191 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2192 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2194 return ToLookup<TSource, TKey, TSource> (source, keySelector, element => element, comparer);
2197 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2198 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2200 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2203 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2204 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2206 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2208 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2209 foreach (var element in source) {
2210 var key = keySelector (element);
2212 throw new ArgumentNullException ("key");
2214 List<TElement> list;
2215 if (!dictionary.TryGetValue (key, out list)) {
2216 list = new List<TElement> ();
2217 dictionary.Add (key, list);
2220 list.Add (elementSelector (element));
2223 return new Lookup<TKey, TElement> (dictionary);
2228 #region SequenceEqual
2230 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2232 return first.SequenceEqual (second, null);
2235 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2237 Check.FirstAndSecond (first, second);
2239 if (comparer == null)
2240 comparer = EqualityComparer<TSource>.Default;
2242 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
2243 second_enumerator = second.GetEnumerator ()) {
2245 while (first_enumerator.MoveNext ()) {
2246 if (!second_enumerator.MoveNext ())
2249 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2253 return !second_enumerator.MoveNext ();
2261 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2263 Check.FirstAndSecond (first, second);
2265 return first.Union (second, null);
2268 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2270 Check.FirstAndSecond (first, second);
2272 if (comparer == null)
2273 comparer = EqualityComparer<TSource>.Default;
2275 return CreateUnionIterator (first, second, comparer);
2278 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2280 var items = new HashSet<TSource> (comparer);
2281 foreach (var element in first) {
2282 if (! items.Contains (element)) {
2283 items.Add (element);
2284 yield return element;
2288 foreach (var element in second) {
2289 if (! items.Contains (element, comparer)) {
2290 items.Add (element);
2291 yield return element;
2300 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2302 Check.SourceAndPredicate (source, predicate);
2304 return CreateWhereIterator (source, predicate);
2307 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2309 foreach (TSource element in source)
2310 if (predicate (element))
2311 yield return element;
2314 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2316 Check.SourceAndPredicate (source, predicate);
2318 return CreateWhereIterator (source, predicate);
2321 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2324 foreach (TSource element in source) {
2325 if (predicate (element, counter))
2326 yield return element;
2333 class ReadOnlyCollectionOf<T> {
2334 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2337 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2340 return ReadOnlyCollectionOf<TSource>.Empty;
2342 var ro = source as ReadOnlyCollection<TSource>;
2346 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());