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 ())
645 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
647 Check.SourceAndSelector (source, selector);
650 foreach (var element in source)
651 if (selector (element))
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> selector)
1267 Check.SourceAndSelector (source, selector);
1270 foreach (TSource element in source)
1271 if (selector (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 long upto = ((long) start + count) - 1;
2168 if (upto > int.MaxValue)
2169 throw new ArgumentOutOfRangeException ();
2171 return CreateRangeIterator (start, (int) upto);
2174 static IEnumerable<int> CreateRangeIterator (int start, int upto)
2176 for (int i = start; i <= upto; i++)
2184 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
2187 throw new ArgumentOutOfRangeException ();
2189 return CreateRepeatIterator (element, count);
2192 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
2194 for (int i = 0; i < count; i++)
2195 yield return element;
2202 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
2204 Check.Source (source);
2206 return CreateReverseIterator (source);
2209 static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
2211 var list = source as IList<TSource>;
2213 list = new List<TSource> (source);
2215 for (int i = list.Count - 1; i >= 0; i--)
2216 yield return list [i];
2223 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2225 Check.SourceAndSelector (source, selector);
2227 return CreateSelectIterator (source, selector);
2230 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
2232 foreach (var element in source)
2233 yield return selector (element);
2236 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2238 Check.SourceAndSelector (source, selector);
2240 return CreateSelectIterator (source, selector);
2243 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2246 foreach (TSource element in source) {
2247 yield return selector (element, counter);
2256 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2258 Check.SourceAndSelector (source, selector);
2260 return CreateSelectManyIterator (source, selector);
2263 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2265 foreach (TSource element in source)
2266 foreach (TResult item in selector (element))
2270 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2272 Check.SourceAndSelector (source, selector);
2274 return CreateSelectManyIterator (source, selector);
2277 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2280 foreach (TSource element in source) {
2281 foreach (TResult item in selector (element, counter))
2287 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2288 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2290 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
2292 return CreateSelectManyIterator (source, collectionSelector, selector);
2295 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2296 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2298 foreach (TSource element in source)
2299 foreach (TCollection collection in collectionSelector (element))
2300 yield return selector (element, collection);
2303 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2304 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2306 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
2308 return CreateSelectManyIterator (source, collectionSelector, selector);
2311 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2312 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2315 foreach (TSource element in source)
2316 foreach (TCollection collection in collectionSelector (element, counter++))
2317 yield return selector (element, collection);
2324 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
2327 var item = default (TSource);
2329 foreach (var element in source) {
2330 if (!predicate (element))
2334 throw new InvalidOperationException ();
2340 if (!found && fallback == Fallback.Throw)
2341 throw new InvalidOperationException ();
2346 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2348 Check.Source (source);
2350 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
2353 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2355 Check.SourceAndPredicate (source, predicate);
2357 return source.Single (predicate, Fallback.Throw);
2362 #region SingleOrDefault
2364 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2366 Check.Source (source);
2368 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
2371 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2373 Check.SourceAndPredicate (source, predicate);
2375 return source.Single (predicate, Fallback.Default);
2382 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2384 Check.Source (source);
2386 return CreateSkipIterator (source, count);
2389 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
2391 var enumerator = source.GetEnumerator ();
2394 if (!enumerator.MoveNext ())
2397 while (enumerator.MoveNext ())
2398 yield return enumerator.Current;
2401 enumerator.Dispose ();
2409 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2411 Check.SourceAndPredicate (source, predicate);
2413 return CreateSkipWhileIterator (source, predicate);
2416 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2420 foreach (TSource element in source) {
2422 yield return element;
2424 if (!predicate (element)) {
2425 yield return element;
2431 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2433 Check.SourceAndPredicate (source, predicate);
2435 return CreateSkipWhileIterator (source, predicate);
2438 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2443 foreach (TSource element in source) {
2445 yield return element;
2447 if (!predicate (element, counter)) {
2448 yield return element;
2459 public static int Sum (this IEnumerable<int> source)
2461 Check.Source (source);
2464 foreach (var element in source)
2465 total = checked (total + element);
2469 public static int? Sum (this IEnumerable<int?> source)
2471 Check.Source (source);
2474 foreach (var element in source) {
2475 if (element.HasValue)
2476 total = checked (total + element.Value);
2481 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2483 Check.SourceAndSelector (source, selector);
2486 foreach (var element in source)
2487 total = checked (total + selector (element));
2492 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2494 Check.SourceAndSelector (source, selector);
2497 foreach (var element in source) {
2498 var value = selector (element);
2500 total = checked (total + value.Value);
2505 public static long Sum (this IEnumerable<long> source)
2507 Check.Source (source);
2511 foreach (var element in source)
2512 total = checked (total + element);
2516 public static long? Sum (this IEnumerable<long?> source)
2518 Check.Source (source);
2521 foreach (var element in source) {
2522 if (element.HasValue)
2523 total = checked (total + element.Value);
2528 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2530 Check.SourceAndSelector (source, selector);
2533 foreach (var element in source)
2534 total = checked (total + selector (element));
2538 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2540 Check.SourceAndSelector (source, selector);
2543 foreach (var element in source) {
2544 var value = selector (element);
2546 total = checked (total + value.Value);
2551 public static double Sum (this IEnumerable<double> source)
2553 Check.Source (source);
2557 foreach (var element in source)
2558 total = checked (total + element);
2562 public static double? Sum (this IEnumerable<double?> source)
2564 Check.Source (source);
2567 foreach (var element in source) {
2568 if (element.HasValue)
2569 total = checked (total + element.Value);
2574 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2576 Check.SourceAndSelector (source, selector);
2580 foreach (var element in source)
2581 total = checked (total + selector (element));
2585 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2587 Check.SourceAndSelector (source, selector);
2590 foreach (var element in source) {
2591 var value = selector (element);
2593 total = checked (total + value.Value);
2598 public static float Sum (this IEnumerable<float> source)
2600 Check.Source (source);
2604 foreach (var element in source)
2605 total = checked (total + element);
2609 public static float? Sum (this IEnumerable<float?> source)
2611 Check.Source (source);
2614 foreach (var element in source) {
2615 if (element.HasValue)
2616 total = checked (total + element.Value);
2622 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2624 Check.SourceAndSelector (source, selector);
2626 foreach (var element in source)
2627 total = checked (total + selector (element));
2631 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2633 Check.SourceAndSelector (source, selector);
2636 foreach (var element in source) {
2637 var value = selector (element);
2639 total = checked (total + value.Value);
2644 public static decimal Sum (this IEnumerable<decimal> source)
2646 Check.Source (source);
2649 foreach (var element in source)
2650 total = checked (total + element);
2654 public static decimal? Sum (this IEnumerable<decimal?> source)
2656 Check.Source (source);
2659 foreach (var element in source) {
2660 if (element.HasValue)
2661 total = checked (total + element.Value);
2667 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2669 Check.SourceAndSelector (source, selector);
2672 foreach (var element in source)
2673 total = checked (total + selector (element));
2677 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2679 Check.SourceAndSelector (source, selector);
2682 foreach (var element in source) {
2683 var value = selector (element);
2685 total = checked (total + value.Value);
2694 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2696 Check.Source (source);
2698 return CreateTakeIterator (source, count);
2701 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2707 foreach (TSource element in source) {
2708 yield return element;
2710 if (++counter == count)
2719 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2721 Check.SourceAndPredicate (source, predicate);
2723 return CreateTakeWhileIterator (source, predicate);
2726 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2728 foreach (var element in source) {
2729 if (!predicate (element))
2732 yield return element;
2736 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2738 Check.SourceAndPredicate (source, predicate);
2740 return CreateTakeWhileIterator (source, predicate);
2743 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2746 foreach (var element in source) {
2747 if (!predicate (element, counter))
2750 yield return element;
2759 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2761 return ThenBy<TSource, TKey> (source, keySelector, null);
2764 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2765 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2767 Check.SourceAndKeySelector (source, keySelector);
2769 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2774 #region ThenByDescending
2776 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2777 Func<TSource, TKey> keySelector)
2779 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2782 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2783 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2785 Check.SourceAndKeySelector (source, keySelector);
2787 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2794 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2796 Check.Source (source);
2798 var collection = source as ICollection<TSource>;
2799 if (collection != null) {
2800 var array = new TSource [collection.Count];
2801 collection.CopyTo (array, 0);
2805 return new List<TSource> (source).ToArray ();
2810 #region ToDictionary
2811 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2812 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2814 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2817 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2818 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2820 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2822 if (comparer == null)
2823 comparer = EqualityComparer<TKey>.Default;
2825 var dict = new Dictionary<TKey, TElement> (comparer);
2826 foreach (var e in source)
2827 dict.Add (keySelector (e), elementSelector (e));
2832 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2833 Func<TSource, TKey> keySelector)
2835 return ToDictionary (source, keySelector, null);
2838 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2839 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2841 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2847 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2849 Check.Source (source);
2851 return new List<TSource> (source);
2857 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2859 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2862 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2863 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2865 return ToLookup<TSource, TKey, TSource> (source, keySelector, element => element, comparer);
2868 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2869 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2871 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2874 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2875 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2877 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2879 List<TElement> nullKeyElements = null;
2881 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2882 foreach (var element in source) {
2883 var key = keySelector (element);
2885 List<TElement> list;
2888 if (nullKeyElements == null)
2889 nullKeyElements = new List<TElement> ();
2891 list = nullKeyElements;
2892 } else if (!dictionary.TryGetValue (key, out list)) {
2893 list = new List<TElement> ();
2894 dictionary.Add (key, list);
2897 list.Add (elementSelector (element));
2900 return new Lookup<TKey, TElement> (dictionary, nullKeyElements);
2905 #region SequenceEqual
2907 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2909 return first.SequenceEqual (second, null);
2912 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2914 Check.FirstAndSecond (first, second);
2916 if (comparer == null)
2917 comparer = EqualityComparer<TSource>.Default;
2919 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
2920 second_enumerator = second.GetEnumerator ()) {
2922 while (first_enumerator.MoveNext ()) {
2923 if (!second_enumerator.MoveNext ())
2926 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2930 return !second_enumerator.MoveNext ();
2938 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2940 Check.FirstAndSecond (first, second);
2942 return first.Union (second, null);
2945 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2947 Check.FirstAndSecond (first, second);
2949 if (comparer == null)
2950 comparer = EqualityComparer<TSource>.Default;
2952 return CreateUnionIterator (first, second, comparer);
2955 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2957 var items = new HashSet<TSource> (comparer);
2958 foreach (var element in first) {
2959 if (! items.Contains (element)) {
2960 items.Add (element);
2961 yield return element;
2965 foreach (var element in second) {
2966 if (! items.Contains (element)) {
2967 items.Add (element);
2968 yield return element;
2975 #if NET_4_0 || MOONLIGHT
2978 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
2980 Check.FirstAndSecond (first, second);
2981 if (resultSelector == null)
2982 throw new ArgumentNullException ("resultSelector");
2984 return CreateZipIterator (first, second, resultSelector);
2987 static IEnumerable<TResult> CreateZipIterator<TFirst, TSecond, TResult> (IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
2989 using (IEnumerator<TFirst> first_enumerator = first.GetEnumerator ()) {
2990 using (IEnumerator<TSecond> second_enumerator = second.GetEnumerator ()) {
2992 while (first_enumerator.MoveNext () && second_enumerator.MoveNext ()) {
2993 yield return selector (first_enumerator.Current, second_enumerator.Current);
3004 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
3006 Check.SourceAndPredicate (source, predicate);
3008 return CreateWhereIterator (source, predicate);
3011 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
3013 foreach (TSource element in source)
3014 if (predicate (element))
3015 yield return element;
3018 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3020 Check.SourceAndPredicate (source, predicate);
3022 return CreateWhereIterator (source, predicate);
3025 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3028 foreach (TSource element in source) {
3029 if (predicate (element, counter))
3030 yield return element;
3037 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
3040 return ReadOnlyCollectionOf<TSource>.Empty;
3042 var ro = source as ReadOnlyCollection<TSource>;
3046 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());