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 static class PredicateOf<T> {
49 public static readonly Func<T, bool> Always = (t) => true;
52 static class Function<T> {
53 public static readonly Func<T, T> Identity = (t) => t;
56 static class EmptyOf<T> {
57 public static readonly T[] Instance = new T [0];
60 static class ReadOnlyCollectionOf<T> {
61 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (EmptyOf<T>.Instance);
66 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
68 Check.SourceAndFunc (source, func);
70 // custom foreach so that we can efficiently throw an exception
71 // if zero elements and treat the first element differently
72 using (var enumerator = source.GetEnumerator ()) {
73 if (!enumerator.MoveNext ())
74 throw new InvalidOperationException ("No elements in source list");
76 TSource folded = enumerator.Current;
77 while (enumerator.MoveNext ())
78 folded = func (folded, enumerator.Current);
83 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
84 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
86 Check.SourceAndFunc (source, func);
88 TAccumulate folded = seed;
89 foreach (TSource element in source)
90 folded = func (folded, element);
95 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
97 Check.SourceAndFunc (source, func);
98 if (resultSelector == null)
99 throw new ArgumentNullException ("resultSelector");
102 foreach (var e in source)
103 result = func (result, e);
105 return resultSelector (result);
112 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
114 Check.SourceAndPredicate (source, predicate);
116 foreach (var element in source)
117 if (!predicate (element))
127 public static bool Any<TSource> (this IEnumerable<TSource> source)
129 Check.Source (source);
131 var collection = source as ICollection<TSource>;
132 if (collection != null)
133 return collection.Count > 0;
135 using (var enumerator = source.GetEnumerator ())
136 return enumerator.MoveNext ();
139 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
141 Check.SourceAndPredicate (source, predicate);
143 foreach (TSource element in source)
144 if (predicate (element))
154 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
163 public static double Average (this IEnumerable<int> source)
165 Check.Source (source);
169 foreach (var element in source){
170 total = checked (total + element);
174 throw new InvalidOperationException ();
175 return total / (double) count;
178 public static double Average (this IEnumerable<long> source)
180 Check.Source (source);
184 foreach (var element in source){
189 throw new InvalidOperationException ();
190 return total / (double) count;
193 public static double Average (this IEnumerable<double> source)
195 Check.Source (source);
199 foreach (var element in source){
204 throw new InvalidOperationException ();
205 return total / count;
208 public static float Average (this IEnumerable<float> source)
210 Check.Source (source);
214 foreach (var element in source){
219 throw new InvalidOperationException ();
220 return total / count;
223 public static decimal Average (this IEnumerable<decimal> source)
225 Check.Source (source);
229 foreach (var element in source){
234 throw new InvalidOperationException ();
235 return total / count;
238 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
239 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
240 where TElement : struct
241 where TAggregate : struct
242 where TResult : struct
244 Check.Source (source);
246 var total = default (TAggregate);
248 foreach (var element in source) {
249 if (!element.HasValue)
252 total = func (total, element.Value);
259 return new TResult? (result (total, counter));
262 public static double? Average (this IEnumerable<int?> source)
264 Check.Source (source);
269 foreach (var element in source) {
270 if (!element.HasValue)
273 total = total + element.Value;
280 return new double? (total / (double) counter);
283 public static double? Average (this IEnumerable<long?> source)
285 Check.Source (source);
290 foreach (var element in source) {
291 if (!element.HasValue)
294 total = checked (total + element.Value);
301 return new double? (total / (double) counter);
305 public static double? Average (this IEnumerable<double?> source)
307 Check.Source (source);
312 foreach (var element in source) {
313 if (!element.HasValue)
316 total = total + element.Value;
323 return new double? (total / counter);
327 public static decimal? Average (this IEnumerable<decimal?> source)
329 Check.Source (source);
334 foreach (var element in source) {
335 if (!element.HasValue)
338 total = total + element.Value;
345 return new decimal? (total / counter);
349 public static float? Average (this IEnumerable<float?> source)
351 Check.Source (source);
356 foreach (var element in source) {
357 if (!element.HasValue)
360 total = total + element.Value;
367 return new float? (total / counter);
371 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
373 Check.SourceAndSelector (source, selector);
377 foreach (var element in source){
378 total += selector (element);
382 throw new InvalidOperationException ();
383 return total / (double) count;
386 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
388 Check.SourceAndSelector (source, selector);
393 foreach (var element in source) {
394 var value = selector (element);
398 total = total + value.Value;
405 return new double? (total / (double) counter);
408 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
410 Check.SourceAndSelector (source, selector);
414 foreach (var element in source){
415 total = checked (total + selector (element));
419 throw new InvalidOperationException ();
420 return total / (double) count;
424 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
426 Check.SourceAndSelector (source, selector);
431 foreach (var element in source) {
432 var value = selector (element);
436 total = checked (total + value.Value);
443 return new double? (total / (double) counter);
446 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
448 Check.SourceAndSelector (source, selector);
452 foreach (var element in source){
453 total += selector (element);
457 throw new InvalidOperationException ();
458 return total / count;
462 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
464 Check.SourceAndSelector (source, selector);
469 foreach (var element in source) {
470 var value = selector (element);
474 total = total + value.Value;
481 return new double? (total / counter);
485 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
487 Check.SourceAndSelector (source, selector);
491 foreach (var element in source){
492 total += selector (element);
496 throw new InvalidOperationException ();
497 return total / count;
500 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
502 Check.SourceAndSelector (source, selector);
507 foreach (var element in source) {
508 var value = selector (element);
512 total = total + value.Value;
519 return new float? (total / counter);
522 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
524 Check.SourceAndSelector (source, selector);
528 foreach (var element in source){
529 total += selector (element);
533 throw new InvalidOperationException ();
534 return total / count;
537 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
539 Check.SourceAndSelector (source, selector);
544 foreach (var element in source) {
545 var value = selector (element);
549 total = total + value.Value;
556 return new decimal? (total / counter);
563 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
565 Check.Source (source);
567 var actual = source as IEnumerable<TResult>;
571 return CreateCastIterator<TResult> (source);
574 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
576 foreach (TResult element in source)
577 yield return element;
584 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
586 Check.FirstAndSecond (first, second);
588 return CreateConcatIterator (first, second);
591 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
593 foreach (TSource element in first)
594 yield return element;
595 foreach (TSource element in second)
596 yield return element;
603 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
605 var collection = source as ICollection<TSource>;
606 if (collection != null)
607 return collection.Contains (value);
609 return Contains<TSource> (source, value, null);
612 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
614 Check.Source (source);
616 if (comparer == null)
617 comparer = EqualityComparer<TSource>.Default;
619 foreach (var element in source)
620 if (comparer.Equals (element, value))
629 public static int Count<TSource> (this IEnumerable<TSource> source)
631 Check.Source (source);
633 var collection = source as ICollection<TSource>;
634 if (collection != null)
635 return collection.Count;
638 using (var enumerator = source.GetEnumerator ())
639 while (enumerator.MoveNext ())
640 checked { counter++; }
645 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
647 Check.SourceAndSelector (source, predicate);
650 foreach (var element in source)
651 if (predicate (element))
652 checked { counter++; }
659 #region DefaultIfEmpty
661 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
663 return DefaultIfEmpty (source, default (TSource));
666 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
668 Check.Source (source);
670 return CreateDefaultIfEmptyIterator (source, defaultValue);
673 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
676 foreach (TSource item in source) {
682 yield return defaultValue;
689 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
691 return Distinct<TSource> (source, null);
694 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
696 Check.Source (source);
698 if (comparer == null)
699 comparer = EqualityComparer<TSource>.Default;
701 return CreateDistinctIterator (source, comparer);
704 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
706 var items = new HashSet<TSource> (comparer);
707 foreach (var element in source) {
708 if (! items.Contains (element)) {
710 yield return element;
719 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
723 foreach (var element in source) {
724 if (index == counter++)
728 if (fallback == Fallback.Throw)
729 throw new ArgumentOutOfRangeException ();
731 return default (TSource);
734 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
736 Check.Source (source);
739 throw new ArgumentOutOfRangeException ();
741 var list = source as IList<TSource>;
745 return source.ElementAt (index, Fallback.Throw);
750 #region ElementAtOrDefault
752 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
754 Check.Source (source);
757 return default (TSource);
759 var list = source as IList<TSource>;
761 return index < list.Count ? list [index] : default (TSource);
763 return source.ElementAt (index, Fallback.Default);
770 public static IEnumerable<TResult> Empty<TResult> ()
772 return EmptyOf<TResult>.Instance;
779 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
781 return Except (first, second, null);
784 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
786 Check.FirstAndSecond (first, second);
788 if (comparer == null)
789 comparer = EqualityComparer<TSource>.Default;
791 return CreateExceptIterator (first, second, comparer);
794 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
796 var items = new HashSet<TSource> (second, comparer);
797 foreach (var element in first) {
798 if (items.Add (element))
799 yield return element;
807 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
809 foreach (var element in source)
810 if (predicate (element))
813 if (fallback == Fallback.Throw)
814 throw new InvalidOperationException ();
816 return default (TSource);
819 public static TSource First<TSource> (this IEnumerable<TSource> source)
821 Check.Source (source);
823 var list = source as IList<TSource>;
828 using (var enumerator = source.GetEnumerator ()) {
829 if (enumerator.MoveNext ())
830 return enumerator.Current;
834 throw new InvalidOperationException ("The source sequence is empty");
837 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
839 Check.SourceAndPredicate (source, predicate);
841 return source.First (predicate, Fallback.Throw);
846 #region FirstOrDefault
848 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
850 Check.Source (source);
852 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
855 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
857 Check.SourceAndPredicate (source, predicate);
859 return source.First (predicate, Fallback.Default);
866 private static List<T> ContainsGroup<K, T> (
867 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
869 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
870 foreach (KeyValuePair<K, List<T>> value in items) {
871 if (comparerInUse.Equals (value.Key, key))
877 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
878 Func<TSource, TKey> keySelector)
880 return GroupBy<TSource, TKey> (source, keySelector, null);
883 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
884 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
886 Check.SourceAndKeySelector (source, keySelector);
888 return CreateGroupByIterator (source, keySelector, comparer);
891 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
892 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
894 var groups = new Dictionary<TKey, List<TSource>> ();
895 var nullList = new List<TSource> ();
897 int nullCounter = -1;
899 foreach (TSource element in source) {
900 TKey key = keySelector (element);
902 nullList.Add (element);
903 if (nullCounter == -1) {
904 nullCounter = counter;
908 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
910 group = new List<TSource> ();
911 groups.Add (key, group);
919 foreach (var group in groups) {
920 if (counter == nullCounter) {
921 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
925 yield return new Grouping<TKey, TSource> (group.Key, group.Value);
929 if (counter == nullCounter) {
930 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
935 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
936 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
938 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
941 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
942 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
944 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
946 return CreateGroupByIterator (source, keySelector, elementSelector, comparer);
949 static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement> (this IEnumerable<TSource> source,
950 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
952 var groups = new Dictionary<TKey, List<TElement>> ();
953 var nullList = new List<TElement> ();
955 int nullCounter = -1;
957 foreach (TSource item in source) {
958 TKey key = keySelector (item);
959 TElement element = elementSelector (item);
961 nullList.Add (element);
962 if (nullCounter == -1) {
963 nullCounter = counter;
967 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
969 group = new List<TElement> ();
970 groups.Add (key, group);
978 foreach (var group in groups) {
979 if (counter == nullCounter) {
980 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
984 yield return new Grouping<TKey, TElement> (group.Key, group.Value);
988 if (counter == nullCounter) {
989 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
994 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
995 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
996 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
998 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
1001 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1002 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1003 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1004 IEqualityComparer<TKey> comparer)
1006 Check.GroupBySelectors (source, keySelector, elementSelector, resultSelector);
1008 return CreateGroupByIterator (source, keySelector, elementSelector, resultSelector, comparer);
1011 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1012 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1013 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1014 IEqualityComparer<TKey> comparer)
1016 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
1017 source, keySelector, elementSelector, comparer);
1019 foreach (IGrouping<TKey, TElement> group in groups)
1020 yield return resultSelector (group.Key, group);
1023 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1024 Func<TSource, TKey> keySelector,
1025 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
1027 return GroupBy (source, keySelector, resultSelector, null);
1030 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1031 Func<TSource, TKey> keySelector,
1032 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1033 IEqualityComparer<TKey> comparer)
1035 Check.SourceAndKeyResultSelectors (source, keySelector, resultSelector);
1037 return CreateGroupByIterator (source, keySelector, resultSelector, comparer);
1040 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1041 Func<TSource, TKey> keySelector,
1042 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1043 IEqualityComparer<TKey> comparer)
1045 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
1047 foreach (IGrouping<TKey, TSource> group in groups)
1048 yield return resultSelector (group.Key, group);
1055 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1056 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1057 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
1059 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
1062 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1063 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1064 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1065 IEqualityComparer<TKey> comparer)
1067 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1069 if (comparer == null)
1070 comparer = EqualityComparer<TKey>.Default;
1072 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1075 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1076 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1077 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1078 IEqualityComparer<TKey> comparer)
1080 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1081 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1082 foreach (U element in inner)
1084 K innerKey = innerKeySelector (element);
1085 if (!innerKeys.ContainsKey (innerKey))
1086 innerKeys.Add (innerKey, new List<U> ());
1087 innerKeys[innerKey].Add (element);
1090 foreach (TOuter element in outer) {
1091 TKey outerKey = outerKeySelector (element);
1092 if (innerKeys.Contains (outerKey))
1093 yield return resultSelector (element, innerKeys [outerKey]);
1095 yield return resultSelector (element, Empty<TInner> ());
1103 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
1105 return Intersect (first, second, null);
1108 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1110 Check.FirstAndSecond (first, second);
1112 if (comparer == null)
1113 comparer = EqualityComparer<TSource>.Default;
1115 return CreateIntersectIterator (first, second, comparer);
1118 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1120 var items = new HashSet<TSource> (second, comparer);
1121 foreach (TSource element in first) {
1122 if (items.Remove (element))
1123 yield return element;
1131 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1132 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1133 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1135 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1137 if (comparer == null)
1138 comparer = EqualityComparer<TKey>.Default;
1140 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1143 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1144 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1145 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1147 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1148 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1149 foreach (U element in inner)
1151 K innerKey = innerKeySelector (element);
1152 if (!innerKeys.ContainsKey (innerKey))
1153 innerKeys.Add (innerKey, new List<U> ());
1154 innerKeys[innerKey].Add (element);
1157 foreach (TOuter element in outer) {
1158 TKey outerKey = outerKeySelector (element);
1159 if (innerKeys.Contains (outerKey)) {
1160 foreach (TInner innerElement in innerKeys [outerKey])
1161 yield return resultSelector (element, innerElement);
1166 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1167 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1168 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
1170 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
1177 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1180 var item = default (TSource);
1182 foreach (var element in source) {
1183 if (!predicate (element))
1193 if (fallback == Fallback.Throw)
1194 throw new InvalidOperationException ();
1199 public static TSource Last<TSource> (this IEnumerable<TSource> source)
1201 Check.Source (source);
1203 var collection = source as ICollection<TSource>;
1204 if (collection != null && collection.Count == 0)
1205 throw new InvalidOperationException ();
1207 var list = source as IList<TSource>;
1209 return list [list.Count - 1];
1211 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
1214 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1216 Check.SourceAndPredicate (source, predicate);
1218 return source.Last (predicate, Fallback.Throw);
1223 #region LastOrDefault
1225 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
1227 Check.Source (source);
1229 var list = source as IList<TSource>;
1231 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
1233 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
1236 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1238 Check.SourceAndPredicate (source, predicate);
1240 return source.Last (predicate, Fallback.Default);
1247 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1249 Check.Source (source);
1252 var array = source as TSource [];
1254 return array.LongLength;
1258 using (var enumerator = source.GetEnumerator ())
1259 while (enumerator.MoveNext ())
1265 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1267 Check.SourceAndSelector (source, predicate);
1270 foreach (TSource element in source)
1271 if (predicate (element))
1281 public static int Max (this IEnumerable<int> source)
1283 Check.Source (source);
1286 var max = int.MinValue;
1287 foreach (var element in source){
1288 max = Math.Max (element, max);
1292 throw new InvalidOperationException ();
1296 public static long Max (this IEnumerable<long> source)
1298 Check.Source (source);
1301 var max = long.MinValue;
1302 foreach (var element in source){
1303 max = Math.Max (element, max);
1307 throw new InvalidOperationException ();
1311 public static double Max (this IEnumerable<double> source)
1313 Check.Source (source);
1316 var max = double.MinValue;
1317 foreach (var element in source){
1318 max = Math.Max (element, max);
1322 throw new InvalidOperationException ();
1326 public static float Max (this IEnumerable<float> source)
1328 Check.Source (source);
1331 var max = float.MinValue;
1332 foreach (var element in source){
1333 max = Math.Max (element, max);
1337 throw new InvalidOperationException ();
1341 public static decimal Max (this IEnumerable<decimal> source)
1343 Check.Source (source);
1346 var max = decimal.MinValue;
1347 foreach (var element in source){
1348 max = Math.Max (element, max);
1352 throw new InvalidOperationException ();
1356 public static int? Max (this IEnumerable<int?> source)
1358 Check.Source (source);
1361 var max = int.MinValue;
1363 foreach (var element in source) {
1364 if (!element.HasValue)
1367 max = Math.Max (element.Value, max);
1377 public static long? Max (this IEnumerable<long?> source)
1379 Check.Source (source);
1382 var max = long.MinValue;
1384 foreach (var element in source) {
1385 if (!element.HasValue)
1388 max = Math.Max (element.Value, max);
1398 public static double? Max (this IEnumerable<double?> source)
1400 Check.Source (source);
1403 var max = double.MinValue;
1405 foreach (var element in source) {
1406 if (!element.HasValue)
1409 max = Math.Max (element.Value, max);
1419 public static float? Max (this IEnumerable<float?> source)
1421 Check.Source (source);
1424 var max = float.MinValue;
1426 foreach (var element in source) {
1427 if (!element.HasValue)
1430 max = Math.Max (element.Value, max);
1440 public static decimal? Max (this IEnumerable<decimal?> source)
1442 Check.Source (source);
1445 var max = decimal.MinValue;
1447 foreach (var element in source) {
1448 if (!element.HasValue)
1451 max = Math.Max (element.Value, max);
1461 // TODO: test nullable and non-nullable
1462 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1464 Check.Source (source);
1466 var comparer = Comparer<TSource>.Default;
1468 TSource max = default (TSource);
1470 if (default (TSource) == null){
1471 foreach (var element in source) {
1472 if (element == null)
1475 if (max == null || comparer.Compare (element, max) > 0)
1480 foreach (var element in source) {
1486 if (comparer.Compare (element, max) > 0)
1490 throw new InvalidOperationException ();
1495 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1497 Check.SourceAndSelector (source, selector);
1500 var max = int.MinValue;
1501 foreach (var element in source){
1502 max = Math.Max (selector (element), max);
1506 throw new InvalidOperationException ();
1510 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1512 Check.SourceAndSelector (source, selector);
1515 var max = long.MinValue;
1516 foreach (var element in source){
1517 max = Math.Max (selector (element), max);
1521 throw new InvalidOperationException ();
1525 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1527 Check.SourceAndSelector (source, selector);
1530 var max = double.MinValue;
1531 foreach (var element in source){
1532 max = Math.Max (selector (element), max);
1536 throw new InvalidOperationException ();
1540 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1542 Check.SourceAndSelector (source, selector);
1545 var max = float.MinValue;
1546 foreach (var element in source){
1547 max = Math.Max (selector (element), max);
1551 throw new InvalidOperationException ();
1555 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1557 Check.SourceAndSelector (source, selector);
1560 var max = decimal.MinValue;
1561 foreach (var element in source){
1562 max = Math.Max (selector (element), max);
1566 throw new InvalidOperationException ();
1570 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1573 foreach (var element in source) {
1574 initValue = selector (element, initValue);
1579 throw new InvalidOperationException ();
1584 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1586 Check.SourceAndSelector (source, selector);
1590 foreach (var element in source) {
1591 int? item = selector (element);
1595 else if (item > max)
1605 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1607 Check.SourceAndSelector (source, selector);
1611 foreach (var element in source) {
1612 long? item = selector (element);
1616 else if (item > max)
1626 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1628 Check.SourceAndSelector (source, selector);
1632 foreach (var element in source) {
1633 double? item = selector (element);
1637 else if (item > max)
1647 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1649 Check.SourceAndSelector (source, selector);
1653 foreach (var element in source) {
1654 float? item = selector (element);
1658 else if (item > max)
1668 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1670 Check.SourceAndSelector (source, selector);
1673 decimal? max = null;
1674 foreach (var element in source) {
1675 decimal? item = selector (element);
1679 else if (item > max)
1689 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1691 Check.SourceAndSelector (source, selector);
1694 return source.Select (selector).Max ();
1701 public static int Min (this IEnumerable<int> source)
1703 Check.Source (source);
1706 var min = int.MaxValue;
1707 foreach (var element in source){
1708 min = Math.Min (element, min);
1712 throw new InvalidOperationException ();
1716 public static long Min (this IEnumerable<long> source)
1718 Check.Source (source);
1721 var min = long.MaxValue;
1722 foreach (var element in source){
1723 min = Math.Min (element, min);
1727 throw new InvalidOperationException ();
1731 public static double Min (this IEnumerable<double> source)
1733 Check.Source (source);
1736 var min = double.MaxValue;
1737 foreach (var element in source){
1738 min = Math.Min (element, min);
1742 throw new InvalidOperationException ();
1746 public static float Min (this IEnumerable<float> source)
1748 Check.Source (source);
1751 var min = float.MaxValue;
1752 foreach (var element in source){
1753 min = Math.Min (element, min);
1757 throw new InvalidOperationException ();
1761 public static decimal Min (this IEnumerable<decimal> source)
1763 Check.Source (source);
1766 var min = decimal.MaxValue;
1767 foreach (var element in source){
1768 min = Math.Min (element, min);
1772 throw new InvalidOperationException ();
1776 public static int? Min (this IEnumerable<int?> source)
1778 Check.Source (source);
1781 var min = int.MaxValue;
1783 foreach (var element in source) {
1784 if (!element.HasValue)
1787 min = Math.Min (element.Value, min);
1797 public static long? Min (this IEnumerable<long?> source)
1799 Check.Source (source);
1802 var min = long.MaxValue;
1804 foreach (var element in source) {
1805 if (!element.HasValue)
1808 min = Math.Min (element.Value, min);
1818 public static double? Min (this IEnumerable<double?> source)
1820 Check.Source (source);
1823 var min = double.MaxValue;
1825 foreach (var element in source) {
1826 if (!element.HasValue)
1829 min = Math.Min (element.Value, min);
1839 public static float? Min (this IEnumerable<float?> source)
1841 Check.Source (source);
1844 var min = float.MaxValue;
1846 foreach (var element in source) {
1847 if (!element.HasValue)
1850 min = Math.Min (element.Value, min);
1860 public static decimal? Min (this IEnumerable<decimal?> source)
1862 Check.Source (source);
1865 var min = decimal.MaxValue;
1867 foreach (var element in source) {
1868 if (!element.HasValue)
1871 min = Math.Min (element.Value, min);
1881 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1883 Check.Source (source);
1885 var comparer = Comparer<TSource>.Default;
1887 TSource min = default (TSource);
1889 if (default (TSource) == null){
1890 foreach (var element in source) {
1891 if (element == null)
1894 if (min == null || comparer.Compare (element, min) < 0)
1899 foreach (var element in source) {
1905 if (comparer.Compare (element, min) < 0)
1909 throw new InvalidOperationException ();
1914 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1916 Check.SourceAndSelector (source, selector);
1919 var min = int.MaxValue;
1920 foreach (var element in source){
1921 min = Math.Min (selector (element), min);
1925 throw new InvalidOperationException ();
1929 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1931 Check.SourceAndSelector (source, selector);
1934 var min = long.MaxValue;
1935 foreach (var element in source){
1936 min = Math.Min (selector (element), min);
1940 throw new InvalidOperationException ();
1944 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1946 Check.SourceAndSelector (source, selector);
1949 var min = double.MaxValue;
1950 foreach (var element in source){
1951 min = Math.Min (selector (element), min);
1955 throw new InvalidOperationException ();
1959 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1961 Check.SourceAndSelector (source, selector);
1964 var min = float.MaxValue;
1965 foreach (var element in source){
1966 min = Math.Min (selector (element), min);
1970 throw new InvalidOperationException ();
1974 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1976 Check.SourceAndSelector (source, selector);
1979 var min = decimal.MaxValue;
1980 foreach (var element in source){
1981 min = Math.Min (selector (element), min);
1985 throw new InvalidOperationException ();
1989 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1991 Check.SourceAndSelector (source, selector);
1995 foreach (var element in source) {
1996 int? item = selector (element);
2000 else if (item < min)
2010 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2012 Check.SourceAndSelector (source, selector);
2016 foreach (var element in source) {
2017 long? item = selector (element);
2021 else if (item < min)
2031 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2033 Check.SourceAndSelector (source, selector);
2037 foreach (var element in source) {
2038 float? item = selector (element);
2042 else if (item < min)
2052 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2054 Check.SourceAndSelector (source, selector);
2058 foreach (var element in source) {
2059 double? item = selector (element);
2063 else if (item < min)
2073 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2075 Check.SourceAndSelector (source, selector);
2078 decimal? min = null;
2079 foreach (var element in source) {
2080 decimal? item = selector (element);
2084 else if (item < min)
2094 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2096 Check.SourceAndSelector (source, selector);
2099 return source.Select (selector).Min ();
2106 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
2108 Check.Source (source);
2110 return CreateOfTypeIterator<TResult> (source);
2113 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
2115 foreach (object element in source)
2116 if (element is TResult)
2117 yield return (TResult) element;
2124 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2125 Func<TSource, TKey> keySelector)
2127 return OrderBy<TSource, TKey> (source, keySelector, null);
2130 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2131 Func<TSource, TKey> keySelector,
2132 IComparer<TKey> comparer)
2134 Check.SourceAndKeySelector (source, keySelector);
2136 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
2141 #region OrderByDescending
2143 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2144 Func<TSource, TKey> keySelector)
2146 return OrderByDescending<TSource, TKey> (source, keySelector, null);
2149 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2150 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2152 Check.SourceAndKeySelector (source, keySelector);
2154 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
2161 public static IEnumerable<int> Range (int start, int count)
2164 throw new ArgumentOutOfRangeException ("count");
2166 if (((long) start + count) - 1L > int.MaxValue)
2167 throw new ArgumentOutOfRangeException ();
2169 return CreateRangeIterator (start, count);
2172 static IEnumerable<int> CreateRangeIterator (int start, int count)
2174 for (int i = 0; i < count; i++)
2175 yield return start + i;
2182 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
2185 throw new ArgumentOutOfRangeException ();
2187 return CreateRepeatIterator (element, count);
2190 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
2192 for (int i = 0; i < count; i++)
2193 yield return element;
2200 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
2202 Check.Source (source);
2204 return CreateReverseIterator (source);
2207 static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
2209 var array = source.ToArray ();
2211 for (int i = array.Length - 1; i >= 0; i--)
2212 yield return array [i];
2219 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2221 Check.SourceAndSelector (source, selector);
2223 return CreateSelectIterator (source, selector);
2226 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
2228 foreach (var element in source)
2229 yield return selector (element);
2232 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2234 Check.SourceAndSelector (source, selector);
2236 return CreateSelectIterator (source, selector);
2239 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2242 foreach (TSource element in source) {
2243 yield return selector (element, counter);
2252 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2254 Check.SourceAndSelector (source, selector);
2256 return CreateSelectManyIterator (source, selector);
2259 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2261 foreach (TSource element in source)
2262 foreach (TResult item in selector (element))
2266 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2268 Check.SourceAndSelector (source, selector);
2270 return CreateSelectManyIterator (source, selector);
2273 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2276 foreach (TSource element in source) {
2277 foreach (TResult item in selector (element, counter))
2283 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2284 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2286 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2288 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2291 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2292 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2294 foreach (TSource element in source)
2295 foreach (TCollection collection in collectionSelector (element))
2296 yield return selector (element, collection);
2299 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2300 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2302 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2304 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2307 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2308 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2311 foreach (TSource element in source)
2312 foreach (TCollection collection in collectionSelector (element, counter++))
2313 yield return selector (element, collection);
2320 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
2323 var item = default (TSource);
2325 foreach (var element in source) {
2326 if (!predicate (element))
2330 throw new InvalidOperationException ();
2336 if (!found && fallback == Fallback.Throw)
2337 throw new InvalidOperationException ();
2342 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2344 Check.Source (source);
2346 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
2349 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2351 Check.SourceAndPredicate (source, predicate);
2353 return source.Single (predicate, Fallback.Throw);
2358 #region SingleOrDefault
2360 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2362 Check.Source (source);
2364 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
2367 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2369 Check.SourceAndPredicate (source, predicate);
2371 return source.Single (predicate, Fallback.Default);
2378 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2380 Check.Source (source);
2382 return CreateSkipIterator (source, count);
2385 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
2387 var enumerator = source.GetEnumerator ();
2390 if (!enumerator.MoveNext ())
2393 while (enumerator.MoveNext ())
2394 yield return enumerator.Current;
2397 enumerator.Dispose ();
2405 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2407 Check.SourceAndPredicate (source, predicate);
2409 return CreateSkipWhileIterator (source, predicate);
2412 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2416 foreach (TSource element in source) {
2418 yield return element;
2420 if (!predicate (element)) {
2421 yield return element;
2427 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2429 Check.SourceAndPredicate (source, predicate);
2431 return CreateSkipWhileIterator (source, predicate);
2434 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2439 foreach (TSource element in source) {
2441 yield return element;
2443 if (!predicate (element, counter)) {
2444 yield return element;
2455 public static int Sum (this IEnumerable<int> source)
2457 Check.Source (source);
2460 foreach (var element in source)
2461 total = checked (total + element);
2465 public static int? Sum (this IEnumerable<int?> source)
2467 Check.Source (source);
2470 foreach (var element in source) {
2471 if (element.HasValue)
2472 total = checked (total + element.Value);
2477 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2479 Check.SourceAndSelector (source, selector);
2482 foreach (var element in source)
2483 total = checked (total + selector (element));
2488 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2490 Check.SourceAndSelector (source, selector);
2493 foreach (var element in source) {
2494 var value = selector (element);
2496 total = checked (total + value.Value);
2501 public static long Sum (this IEnumerable<long> source)
2503 Check.Source (source);
2507 foreach (var element in source)
2508 total = checked (total + element);
2512 public static long? Sum (this IEnumerable<long?> source)
2514 Check.Source (source);
2517 foreach (var element in source) {
2518 if (element.HasValue)
2519 total = checked (total + element.Value);
2524 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2526 Check.SourceAndSelector (source, selector);
2529 foreach (var element in source)
2530 total = checked (total + selector (element));
2534 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2536 Check.SourceAndSelector (source, selector);
2539 foreach (var element in source) {
2540 var value = selector (element);
2542 total = checked (total + value.Value);
2547 public static double Sum (this IEnumerable<double> source)
2549 Check.Source (source);
2553 foreach (var element in source)
2554 total = checked (total + element);
2558 public static double? Sum (this IEnumerable<double?> source)
2560 Check.Source (source);
2563 foreach (var element in source) {
2564 if (element.HasValue)
2565 total = checked (total + element.Value);
2570 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2572 Check.SourceAndSelector (source, selector);
2576 foreach (var element in source)
2577 total = checked (total + selector (element));
2581 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2583 Check.SourceAndSelector (source, selector);
2586 foreach (var element in source) {
2587 var value = selector (element);
2589 total = checked (total + value.Value);
2594 public static float Sum (this IEnumerable<float> source)
2596 Check.Source (source);
2600 foreach (var element in source)
2601 total = checked (total + element);
2605 public static float? Sum (this IEnumerable<float?> source)
2607 Check.Source (source);
2610 foreach (var element in source) {
2611 if (element.HasValue)
2612 total = checked (total + element.Value);
2618 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2620 Check.SourceAndSelector (source, selector);
2622 foreach (var element in source)
2623 total = checked (total + selector (element));
2627 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2629 Check.SourceAndSelector (source, selector);
2632 foreach (var element in source) {
2633 var value = selector (element);
2635 total = checked (total + value.Value);
2640 public static decimal Sum (this IEnumerable<decimal> source)
2642 Check.Source (source);
2645 foreach (var element in source)
2646 total = checked (total + element);
2650 public static decimal? Sum (this IEnumerable<decimal?> source)
2652 Check.Source (source);
2655 foreach (var element in source) {
2656 if (element.HasValue)
2657 total = checked (total + element.Value);
2663 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2665 Check.SourceAndSelector (source, selector);
2668 foreach (var element in source)
2669 total = checked (total + selector (element));
2673 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2675 Check.SourceAndSelector (source, selector);
2678 foreach (var element in source) {
2679 var value = selector (element);
2681 total = checked (total + value.Value);
2690 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2692 Check.Source (source);
2694 return CreateTakeIterator (source, count);
2697 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2703 foreach (TSource element in source) {
2704 yield return element;
2706 if (++counter == count)
2715 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2717 Check.SourceAndPredicate (source, predicate);
2719 return CreateTakeWhileIterator (source, predicate);
2722 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2724 foreach (var element in source) {
2725 if (!predicate (element))
2728 yield return element;
2732 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2734 Check.SourceAndPredicate (source, predicate);
2736 return CreateTakeWhileIterator (source, predicate);
2739 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2742 foreach (var element in source) {
2743 if (!predicate (element, counter))
2746 yield return element;
2755 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2757 return ThenBy<TSource, TKey> (source, keySelector, null);
2760 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2761 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2763 Check.SourceAndKeySelector (source, keySelector);
2765 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2770 #region ThenByDescending
2772 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2773 Func<TSource, TKey> keySelector)
2775 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2778 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2779 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2781 Check.SourceAndKeySelector (source, keySelector);
2783 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2790 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2792 Check.Source (source);
2795 var collection = source as ICollection<TSource>;
2796 if (collection != null) {
2797 if (collection.Count == 0)
2798 return EmptyOf<TSource>.Instance;
2800 array = new TSource [collection.Count];
2801 collection.CopyTo (array, 0);
2806 array = EmptyOf<TSource>.Instance;
2807 foreach (var element in source) {
2808 if (pos == array.Length) {
2810 array = new TSource [4];
2812 Array.Resize (ref array, pos * 2);
2815 array[pos++] = element;
2818 if (pos != array.Length)
2819 Array.Resize (ref array, pos);
2826 #region ToDictionary
2827 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2828 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2830 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2833 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2834 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2836 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2838 if (comparer == null)
2839 comparer = EqualityComparer<TKey>.Default;
2841 var dict = new Dictionary<TKey, TElement> (comparer);
2842 foreach (var e in source)
2843 dict.Add (keySelector (e), elementSelector (e));
2848 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2849 Func<TSource, TKey> keySelector)
2851 return ToDictionary (source, keySelector, null);
2854 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2855 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2857 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2863 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2865 Check.Source (source);
2867 return new List<TSource> (source);
2873 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2875 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2878 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2879 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2881 return ToLookup<TSource, TKey, TSource> (source, keySelector, element => element, comparer);
2884 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2885 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2887 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2890 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2891 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2893 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2895 List<TElement> nullKeyElements = null;
2897 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2898 foreach (var element in source) {
2899 var key = keySelector (element);
2901 List<TElement> list;
2904 if (nullKeyElements == null)
2905 nullKeyElements = new List<TElement> ();
2907 list = nullKeyElements;
2908 } else if (!dictionary.TryGetValue (key, out list)) {
2909 list = new List<TElement> ();
2910 dictionary.Add (key, list);
2913 list.Add (elementSelector (element));
2916 return new Lookup<TKey, TElement> (dictionary, nullKeyElements);
2921 #region SequenceEqual
2923 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2925 return first.SequenceEqual (second, null);
2928 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2930 Check.FirstAndSecond (first, second);
2932 if (comparer == null)
2933 comparer = EqualityComparer<TSource>.Default;
2935 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
2936 second_enumerator = second.GetEnumerator ()) {
2938 while (first_enumerator.MoveNext ()) {
2939 if (!second_enumerator.MoveNext ())
2942 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2946 return !second_enumerator.MoveNext ();
2954 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2956 Check.FirstAndSecond (first, second);
2958 return first.Union (second, null);
2961 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2963 Check.FirstAndSecond (first, second);
2965 if (comparer == null)
2966 comparer = EqualityComparer<TSource>.Default;
2968 return CreateUnionIterator (first, second, comparer);
2971 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2973 var items = new HashSet<TSource> (comparer);
2974 foreach (var element in first) {
2975 if (! items.Contains (element)) {
2976 items.Add (element);
2977 yield return element;
2981 foreach (var element in second) {
2982 if (! items.Contains (element)) {
2983 items.Add (element);
2984 yield return element;
2991 #if NET_4_0 || MOONLIGHT || MOBILE
2994 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
2996 Check.FirstAndSecond (first, second);
2997 if (resultSelector == null)
2998 throw new ArgumentNullException ("resultSelector");
3000 return CreateZipIterator (first, second, resultSelector);
3003 static IEnumerable<TResult> CreateZipIterator<TFirst, TSecond, TResult> (IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
3005 using (IEnumerator<TFirst> first_enumerator = first.GetEnumerator ()) {
3006 using (IEnumerator<TSecond> second_enumerator = second.GetEnumerator ()) {
3008 while (first_enumerator.MoveNext () && second_enumerator.MoveNext ()) {
3009 yield return selector (first_enumerator.Current, second_enumerator.Current);
3020 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
3022 Check.SourceAndPredicate (source, predicate);
3024 return CreateWhereIterator (source, predicate);
3027 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
3029 foreach (TSource element in source)
3030 if (predicate (element))
3031 yield return element;
3034 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3036 Check.SourceAndPredicate (source, predicate);
3038 return CreateWhereIterator (source, predicate);
3041 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3044 foreach (TSource element in source) {
3045 if (predicate (element, counter))
3046 yield return element;
3053 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
3056 return ReadOnlyCollectionOf<TSource>.Empty;
3058 var ro = source as ReadOnlyCollection<TSource>;
3062 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());