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
49 static class PredicateOf<T> {
50 public static readonly Func<T, bool> Always = (t) => true;
54 static class Function<T> {
55 public static readonly Func<T, T> Identity = (t) => t;
58 static class EmptyOf<T> {
59 public static readonly T[] Instance = new T [0];
62 static class ReadOnlyCollectionOf<T> {
63 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (EmptyOf<T>.Instance);
68 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
70 Check.SourceAndFunc (source, func);
72 // custom foreach so that we can efficiently throw an exception
73 // if zero elements and treat the first element differently
74 using (var enumerator = source.GetEnumerator ()) {
75 if (!enumerator.MoveNext ())
76 throw EmptySequence ();
78 TSource folded = enumerator.Current;
79 while (enumerator.MoveNext ())
80 folded = func (folded, enumerator.Current);
85 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
86 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
88 Check.SourceAndFunc (source, func);
90 TAccumulate folded = seed;
91 foreach (TSource element in source)
92 folded = func (folded, element);
97 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
99 Check.SourceAndFunc (source, func);
100 if (resultSelector == null)
101 throw new ArgumentNullException ("resultSelector");
104 foreach (var e in source)
105 result = func (result, e);
107 return resultSelector (result);
114 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
116 Check.SourceAndPredicate (source, predicate);
118 foreach (var element in source)
119 if (!predicate (element))
129 public static bool Any<TSource> (this IEnumerable<TSource> source)
131 Check.Source (source);
133 var collection = source as ICollection<TSource>;
134 if (collection != null)
135 return collection.Count > 0;
137 using (var enumerator = source.GetEnumerator ())
138 return enumerator.MoveNext ();
141 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
143 Check.SourceAndPredicate (source, predicate);
145 foreach (TSource element in source)
146 if (predicate (element))
156 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
165 public static double Average (this IEnumerable<int> source)
167 Check.Source (source);
171 foreach (var element in source){
172 total = checked (total + element);
176 throw EmptySequence ();
177 return total / (double) count;
180 public static double Average (this IEnumerable<long> source)
182 Check.Source (source);
186 foreach (var element in source){
191 throw EmptySequence ();
192 return total / (double) count;
195 public static double Average (this IEnumerable<double> source)
197 Check.Source (source);
201 foreach (var element in source){
206 throw EmptySequence ();
207 return total / count;
210 public static float Average (this IEnumerable<float> source)
212 Check.Source (source);
216 foreach (var element in source){
221 throw EmptySequence ();
222 return total / count;
225 public static decimal Average (this IEnumerable<decimal> source)
227 Check.Source (source);
231 foreach (var element in source){
236 throw EmptySequence ();
237 return total / count;
240 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
241 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
242 where TElement : struct
243 where TAggregate : struct
244 where TResult : struct
246 Check.Source (source);
248 var total = default (TAggregate);
250 foreach (var element in source) {
251 if (!element.HasValue)
254 total = func (total, element.Value);
261 return new TResult? (result (total, counter));
264 public static double? Average (this IEnumerable<int?> source)
266 Check.Source (source);
271 foreach (var element in source) {
272 if (!element.HasValue)
275 total = total + element.Value;
282 return new double? (total / (double) counter);
285 public static double? Average (this IEnumerable<long?> source)
287 Check.Source (source);
292 foreach (var element in source) {
293 if (!element.HasValue)
296 total = checked (total + element.Value);
303 return new double? (total / (double) counter);
307 public static double? Average (this IEnumerable<double?> source)
309 Check.Source (source);
314 foreach (var element in source) {
315 if (!element.HasValue)
318 total = total + element.Value;
325 return new double? (total / counter);
329 public static decimal? Average (this IEnumerable<decimal?> source)
331 Check.Source (source);
336 foreach (var element in source) {
337 if (!element.HasValue)
340 total = total + element.Value;
347 return new decimal? (total / counter);
351 public static float? Average (this IEnumerable<float?> source)
353 Check.Source (source);
358 foreach (var element in source) {
359 if (!element.HasValue)
362 total = total + element.Value;
369 return new float? (total / counter);
373 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
375 Check.SourceAndSelector (source, selector);
379 foreach (var element in source){
380 total += selector (element);
384 throw EmptySequence ();
385 return total / (double) count;
388 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
390 Check.SourceAndSelector (source, selector);
395 foreach (var element in source) {
396 var value = selector (element);
400 total = total + value.Value;
407 return new double? (total / (double) counter);
410 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
412 Check.SourceAndSelector (source, selector);
416 foreach (var element in source){
417 total = checked (total + selector (element));
421 throw EmptySequence ();
422 return total / (double) count;
426 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
428 Check.SourceAndSelector (source, selector);
433 foreach (var element in source) {
434 var value = selector (element);
438 total = checked (total + value.Value);
445 return new double? (total / (double) counter);
448 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
450 Check.SourceAndSelector (source, selector);
454 foreach (var element in source){
455 total += selector (element);
459 throw EmptySequence ();
460 return total / count;
464 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
466 Check.SourceAndSelector (source, selector);
471 foreach (var element in source) {
472 var value = selector (element);
476 total = total + value.Value;
483 return new double? (total / counter);
487 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
489 Check.SourceAndSelector (source, selector);
493 foreach (var element in source){
494 total += selector (element);
498 throw EmptySequence ();
499 return total / count;
502 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
504 Check.SourceAndSelector (source, selector);
509 foreach (var element in source) {
510 var value = selector (element);
514 total = total + value.Value;
521 return new float? (total / counter);
524 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
526 Check.SourceAndSelector (source, selector);
530 foreach (var element in source){
531 total += selector (element);
535 throw EmptySequence ();
536 return total / count;
539 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
541 Check.SourceAndSelector (source, selector);
546 foreach (var element in source) {
547 var value = selector (element);
551 total = total + value.Value;
558 return new decimal? (total / counter);
565 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
567 Check.Source (source);
569 var actual = source as IEnumerable<TResult>;
573 return CreateCastIterator<TResult> (source);
576 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
578 foreach (TResult element in source)
579 yield return element;
586 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
588 Check.FirstAndSecond (first, second);
590 return CreateConcatIterator (first, second);
593 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
595 foreach (TSource element in first)
596 yield return element;
597 foreach (TSource element in second)
598 yield return element;
605 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
607 var collection = source as ICollection<TSource>;
608 if (collection != null)
609 return collection.Contains (value);
611 return Contains<TSource> (source, value, null);
614 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
616 Check.Source (source);
618 if (comparer == null)
619 comparer = EqualityComparer<TSource>.Default;
621 foreach (var element in source)
622 if (comparer.Equals (element, value))
631 public static int Count<TSource> (this IEnumerable<TSource> source)
633 Check.Source (source);
635 var collection = source as ICollection<TSource>;
636 if (collection != null)
637 return collection.Count;
640 using (var enumerator = source.GetEnumerator ())
641 while (enumerator.MoveNext ())
642 checked { counter++; }
647 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
649 Check.SourceAndSelector (source, predicate);
652 foreach (var element in source)
653 if (predicate (element))
654 checked { counter++; }
661 #region DefaultIfEmpty
663 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
665 return DefaultIfEmpty (source, default (TSource));
668 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
670 Check.Source (source);
672 return CreateDefaultIfEmptyIterator (source, defaultValue);
675 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
678 foreach (TSource item in source) {
684 yield return defaultValue;
691 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
693 return Distinct<TSource> (source, null);
696 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
698 Check.Source (source);
700 if (comparer == null)
701 comparer = EqualityComparer<TSource>.Default;
703 return CreateDistinctIterator (source, comparer);
706 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
708 var items = new HashSet<TSource> (comparer);
709 foreach (var element in source) {
710 if (! items.Contains (element)) {
712 yield return element;
721 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
725 foreach (var element in source) {
726 if (index == counter++)
730 if (fallback == Fallback.Throw)
731 throw new ArgumentOutOfRangeException ();
733 return default (TSource);
736 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
738 Check.Source (source);
741 throw new ArgumentOutOfRangeException ();
743 var list = source as IList<TSource>;
748 var readOnlyList = source as IReadOnlyList<TSource>;
749 if (readOnlyList != null)
750 return readOnlyList[index];
753 return source.ElementAt (index, Fallback.Throw);
758 #region ElementAtOrDefault
760 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
762 Check.Source (source);
765 return default (TSource);
767 var list = source as IList<TSource>;
769 return index < list.Count ? list [index] : default (TSource);
772 var readOnlyList = source as IReadOnlyList<TSource>;
773 if (readOnlyList != null)
774 return index < readOnlyList.Count ? readOnlyList [index] : default (TSource);
777 return source.ElementAt (index, Fallback.Default);
784 public static IEnumerable<TResult> Empty<TResult> ()
786 return EmptyOf<TResult>.Instance;
793 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
795 return Except (first, second, null);
798 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
800 Check.FirstAndSecond (first, second);
802 if (comparer == null)
803 comparer = EqualityComparer<TSource>.Default;
805 return CreateExceptIterator (first, second, comparer);
808 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
810 var items = new HashSet<TSource> (second, comparer);
811 foreach (var element in first) {
812 if (items.Add (element))
813 yield return element;
821 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
823 foreach (var element in source)
824 if (predicate (element))
827 if (fallback == Fallback.Throw)
828 throw NoMatchingElement ();
830 return default (TSource);
833 public static TSource First<TSource> (this IEnumerable<TSource> source)
835 Check.Source (source);
837 var list = source as IList<TSource>;
842 using (var enumerator = source.GetEnumerator ()) {
843 if (enumerator.MoveNext ())
844 return enumerator.Current;
848 throw EmptySequence ();
851 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
853 Check.SourceAndPredicate (source, predicate);
855 return source.First (predicate, Fallback.Throw);
860 #region FirstOrDefault
862 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
864 Check.Source (source);
866 #if !FULL_AOT_RUNTIME
867 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
869 // inline the code to reduce dependency o generic causing AOT errors on device (e.g. bug #3285)
870 foreach (var element in source)
873 return default (TSource);
877 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
879 Check.SourceAndPredicate (source, predicate);
881 return source.First (predicate, Fallback.Default);
888 private static List<T> ContainsGroup<K, T> (
889 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
891 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
892 foreach (KeyValuePair<K, List<T>> value in items) {
893 if (comparerInUse.Equals (value.Key, key))
899 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
900 Func<TSource, TKey> keySelector)
902 return GroupBy<TSource, TKey> (source, keySelector, null);
905 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
906 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
908 Check.SourceAndKeySelector (source, keySelector);
910 return CreateGroupByIterator (source, keySelector, comparer);
913 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
914 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
916 var groups = new Dictionary<TKey, List<TSource>> ();
917 var nullList = new List<TSource> ();
919 int nullCounter = -1;
921 foreach (TSource element in source) {
922 TKey key = keySelector (element);
924 nullList.Add (element);
925 if (nullCounter == -1) {
926 nullCounter = counter;
930 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
932 group = new List<TSource> ();
933 groups.Add (key, group);
941 foreach (var group in groups) {
942 if (counter == nullCounter) {
943 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
947 yield return new Grouping<TKey, TSource> (group.Key, group.Value);
951 if (counter == nullCounter) {
952 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
957 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
958 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
960 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
963 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
964 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
966 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
968 return CreateGroupByIterator (source, keySelector, elementSelector, comparer);
971 static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement> (this IEnumerable<TSource> source,
972 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
974 var groups = new Dictionary<TKey, List<TElement>> ();
975 var nullList = new List<TElement> ();
977 int nullCounter = -1;
979 foreach (TSource item in source) {
980 TKey key = keySelector (item);
981 TElement element = elementSelector (item);
983 nullList.Add (element);
984 if (nullCounter == -1) {
985 nullCounter = counter;
989 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
991 group = new List<TElement> ();
992 groups.Add (key, group);
1000 foreach (var group in groups) {
1001 if (counter == nullCounter) {
1002 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
1006 yield return new Grouping<TKey, TElement> (group.Key, group.Value);
1010 if (counter == nullCounter) {
1011 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
1016 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1017 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1018 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
1020 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
1023 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1024 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1025 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1026 IEqualityComparer<TKey> comparer)
1028 Check.GroupBySelectors (source, keySelector, elementSelector, resultSelector);
1030 return CreateGroupByIterator (source, keySelector, elementSelector, resultSelector, comparer);
1033 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1034 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1035 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1036 IEqualityComparer<TKey> comparer)
1038 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
1039 source, keySelector, elementSelector, comparer);
1041 foreach (IGrouping<TKey, TElement> group in groups)
1042 yield return resultSelector (group.Key, group);
1045 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1046 Func<TSource, TKey> keySelector,
1047 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
1049 return GroupBy (source, keySelector, resultSelector, null);
1052 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1053 Func<TSource, TKey> keySelector,
1054 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1055 IEqualityComparer<TKey> comparer)
1057 Check.SourceAndKeyResultSelectors (source, keySelector, resultSelector);
1059 return CreateGroupByIterator (source, keySelector, resultSelector, comparer);
1062 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1063 Func<TSource, TKey> keySelector,
1064 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1065 IEqualityComparer<TKey> comparer)
1067 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
1069 foreach (IGrouping<TKey, TSource> group in groups)
1070 yield return resultSelector (group.Key, group);
1077 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1078 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1079 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
1081 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
1084 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1085 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1086 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1087 IEqualityComparer<TKey> comparer)
1089 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1091 if (comparer == null)
1092 comparer = EqualityComparer<TKey>.Default;
1094 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1097 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1098 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1099 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1100 IEqualityComparer<TKey> comparer)
1102 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1103 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1104 foreach (U element in inner)
1106 K innerKey = innerKeySelector (element);
1107 if (!innerKeys.ContainsKey (innerKey))
1108 innerKeys.Add (innerKey, new List<U> ());
1109 innerKeys[innerKey].Add (element);
1112 foreach (TOuter element in outer) {
1113 TKey outerKey = outerKeySelector (element);
1114 if (outerKey != null && innerKeys.Contains (outerKey))
1115 yield return resultSelector (element, innerKeys [outerKey]);
1117 yield return resultSelector (element, Empty<TInner> ());
1125 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
1127 return Intersect (first, second, null);
1130 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1132 Check.FirstAndSecond (first, second);
1134 if (comparer == null)
1135 comparer = EqualityComparer<TSource>.Default;
1137 return CreateIntersectIterator (first, second, comparer);
1140 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1142 var items = new HashSet<TSource> (second, comparer);
1143 foreach (TSource element in first) {
1144 if (items.Remove (element))
1145 yield return element;
1153 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1154 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1155 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1157 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1159 if (comparer == null)
1160 comparer = EqualityComparer<TKey>.Default;
1162 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1165 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1166 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1167 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1169 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1170 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1171 foreach (U element in inner)
1173 K innerKey = innerKeySelector (element);
1174 if (!innerKeys.ContainsKey (innerKey))
1175 innerKeys.Add (innerKey, new List<U> ());
1176 innerKeys[innerKey].Add (element);
1179 foreach (TOuter element in outer) {
1180 TKey outerKey = outerKeySelector (element);
1181 if (outerKey != null && innerKeys.Contains (outerKey)) {
1182 foreach (TInner innerElement in innerKeys [outerKey])
1183 yield return resultSelector (element, innerElement);
1188 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1189 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1190 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
1192 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
1199 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1202 var item = default (TSource);
1204 foreach (var element in source) {
1205 if (!predicate (element))
1215 if (fallback == Fallback.Throw)
1216 throw NoMatchingElement ();
1221 public static TSource Last<TSource> (this IEnumerable<TSource> source)
1223 Check.Source (source);
1225 var collection = source as ICollection<TSource>;
1226 if (collection != null && collection.Count == 0)
1227 throw EmptySequence ();
1229 var list = source as IList<TSource>;
1231 return list [list.Count - 1];
1233 #if !FULL_AOT_RUNTIME
1234 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
1237 var item = default (TSource);
1239 foreach (var element in source) {
1247 throw EmptySequence ();
1251 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1253 Check.SourceAndPredicate (source, predicate);
1255 return source.Last (predicate, Fallback.Throw);
1260 #region LastOrDefault
1262 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
1264 Check.Source (source);
1266 var list = source as IList<TSource>;
1268 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
1270 #if !FULL_AOT_RUNTIME
1271 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
1274 var item = default (TSource);
1276 foreach (var element in source) {
1288 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1290 Check.SourceAndPredicate (source, predicate);
1292 return source.Last (predicate, Fallback.Default);
1299 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1301 Check.Source (source);
1304 var array = source as TSource [];
1306 return array.LongLength;
1310 using (var enumerator = source.GetEnumerator ())
1311 while (enumerator.MoveNext ())
1317 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1319 Check.SourceAndSelector (source, predicate);
1322 foreach (TSource element in source)
1323 if (predicate (element))
1333 public static int Max (this IEnumerable<int> source)
1335 Check.Source (source);
1338 var max = int.MinValue;
1339 foreach (var element in source){
1340 max = Math.Max (element, max);
1344 throw EmptySequence();
1348 public static long Max (this IEnumerable<long> source)
1350 Check.Source (source);
1353 var max = long.MinValue;
1354 foreach (var element in source){
1355 max = Math.Max (element, max);
1359 throw EmptySequence ();
1363 public static double Max (this IEnumerable<double> source)
1365 Check.Source (source);
1368 var max = double.MinValue;
1369 foreach (var element in source){
1370 max = Math.Max (element, max);
1374 throw EmptySequence ();
1378 public static float Max (this IEnumerable<float> source)
1380 Check.Source (source);
1383 var max = float.MinValue;
1384 foreach (var element in source){
1385 max = Math.Max (element, max);
1389 throw EmptySequence ();
1393 public static decimal Max (this IEnumerable<decimal> source)
1395 Check.Source (source);
1398 var max = decimal.MinValue;
1399 foreach (var element in source){
1400 max = Math.Max (element, max);
1404 throw EmptySequence ();
1408 public static int? Max (this IEnumerable<int?> source)
1410 Check.Source (source);
1413 var max = int.MinValue;
1415 foreach (var element in source) {
1416 if (!element.HasValue)
1419 max = Math.Max (element.Value, max);
1429 public static long? Max (this IEnumerable<long?> source)
1431 Check.Source (source);
1434 var max = long.MinValue;
1436 foreach (var element in source) {
1437 if (!element.HasValue)
1440 max = Math.Max (element.Value, max);
1450 public static double? Max (this IEnumerable<double?> source)
1452 Check.Source (source);
1455 var max = double.MinValue;
1457 foreach (var element in source) {
1458 if (!element.HasValue)
1461 max = Math.Max (element.Value, max);
1471 public static float? Max (this IEnumerable<float?> source)
1473 Check.Source (source);
1476 var max = float.MinValue;
1478 foreach (var element in source) {
1479 if (!element.HasValue)
1482 max = Math.Max (element.Value, max);
1492 public static decimal? Max (this IEnumerable<decimal?> source)
1494 Check.Source (source);
1497 var max = decimal.MinValue;
1499 foreach (var element in source) {
1500 if (!element.HasValue)
1503 max = Math.Max (element.Value, max);
1513 // TODO: test nullable and non-nullable
1514 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1516 Check.Source (source);
1518 var comparer = Comparer<TSource>.Default;
1520 TSource max = default (TSource);
1522 if (default (TSource) == null){
1523 foreach (var element in source) {
1524 if (element == null)
1527 if (max == null || comparer.Compare (element, max) > 0)
1532 foreach (var element in source) {
1538 if (comparer.Compare (element, max) > 0)
1542 throw EmptySequence ();
1547 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1549 Check.SourceAndSelector (source, selector);
1552 var max = int.MinValue;
1553 foreach (var element in source){
1554 max = Math.Max (selector (element), max);
1558 throw NoMatchingElement ();
1562 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1564 Check.SourceAndSelector (source, selector);
1567 var max = long.MinValue;
1568 foreach (var element in source){
1569 max = Math.Max (selector (element), max);
1573 throw NoMatchingElement ();
1577 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1579 Check.SourceAndSelector (source, selector);
1582 var max = double.MinValue;
1583 foreach (var element in source){
1584 max = Math.Max (selector (element), max);
1588 throw NoMatchingElement ();
1592 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1594 Check.SourceAndSelector (source, selector);
1597 var max = float.MinValue;
1598 foreach (var element in source){
1599 max = Math.Max (selector (element), max);
1603 throw NoMatchingElement ();
1607 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1609 Check.SourceAndSelector (source, selector);
1612 var max = decimal.MinValue;
1613 foreach (var element in source){
1614 max = Math.Max (selector (element), max);
1618 throw NoMatchingElement ();
1622 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1625 foreach (var element in source) {
1626 initValue = selector (element, initValue);
1631 throw NoMatchingElement ();
1636 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1638 Check.SourceAndSelector (source, selector);
1642 foreach (var element in source) {
1643 int? item = selector (element);
1647 else if (item > max)
1657 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1659 Check.SourceAndSelector (source, selector);
1663 foreach (var element in source) {
1664 long? item = selector (element);
1668 else if (item > max)
1678 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1680 Check.SourceAndSelector (source, selector);
1684 foreach (var element in source) {
1685 double? item = selector (element);
1689 else if (item > max)
1699 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1701 Check.SourceAndSelector (source, selector);
1705 foreach (var element in source) {
1706 float? item = selector (element);
1710 else if (item > max)
1720 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1722 Check.SourceAndSelector (source, selector);
1725 decimal? max = null;
1726 foreach (var element in source) {
1727 decimal? item = selector (element);
1731 else if (item > max)
1741 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1743 Check.SourceAndSelector (source, selector);
1746 return source.Select (selector).Max ();
1753 public static int Min (this IEnumerable<int> source)
1755 Check.Source (source);
1758 var min = int.MaxValue;
1759 foreach (var element in source){
1760 min = Math.Min (element, min);
1764 throw EmptySequence ();
1768 public static long Min (this IEnumerable<long> source)
1770 Check.Source (source);
1773 var min = long.MaxValue;
1774 foreach (var element in source){
1775 min = Math.Min (element, min);
1779 throw EmptySequence ();
1783 public static double Min (this IEnumerable<double> source)
1785 Check.Source (source);
1788 var min = double.MaxValue;
1789 foreach (var element in source){
1790 min = Math.Min (element, min);
1794 throw EmptySequence ();
1798 public static float Min (this IEnumerable<float> source)
1800 Check.Source (source);
1803 var min = float.MaxValue;
1804 foreach (var element in source){
1805 min = Math.Min (element, min);
1809 throw EmptySequence ();
1813 public static decimal Min (this IEnumerable<decimal> source)
1815 Check.Source (source);
1818 var min = decimal.MaxValue;
1819 foreach (var element in source){
1820 min = Math.Min (element, min);
1824 throw EmptySequence ();
1828 public static int? Min (this IEnumerable<int?> source)
1830 Check.Source (source);
1833 var min = int.MaxValue;
1835 foreach (var element in source) {
1836 if (!element.HasValue)
1839 min = Math.Min (element.Value, min);
1849 public static long? Min (this IEnumerable<long?> source)
1851 Check.Source (source);
1854 var min = long.MaxValue;
1856 foreach (var element in source) {
1857 if (!element.HasValue)
1860 min = Math.Min (element.Value, min);
1870 public static double? Min (this IEnumerable<double?> source)
1872 Check.Source (source);
1875 var min = double.MaxValue;
1877 foreach (var element in source) {
1878 if (!element.HasValue)
1881 min = Math.Min (element.Value, min);
1891 public static float? Min (this IEnumerable<float?> source)
1893 Check.Source (source);
1896 var min = float.MaxValue;
1898 foreach (var element in source) {
1899 if (!element.HasValue)
1902 min = Math.Min (element.Value, min);
1912 public static decimal? Min (this IEnumerable<decimal?> source)
1914 Check.Source (source);
1917 var min = decimal.MaxValue;
1919 foreach (var element in source) {
1920 if (!element.HasValue)
1923 min = Math.Min (element.Value, min);
1933 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1935 Check.Source (source);
1937 var comparer = Comparer<TSource>.Default;
1939 TSource min = default (TSource);
1941 if (default (TSource) == null){
1942 foreach (var element in source) {
1943 if (element == null)
1946 if (min == null || comparer.Compare (element, min) < 0)
1951 foreach (var element in source) {
1957 if (comparer.Compare (element, min) < 0)
1961 throw EmptySequence ();
1966 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1968 Check.SourceAndSelector (source, selector);
1971 var min = int.MaxValue;
1972 foreach (var element in source){
1973 min = Math.Min (selector (element), min);
1977 throw NoMatchingElement ();
1981 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1983 Check.SourceAndSelector (source, selector);
1986 var min = long.MaxValue;
1987 foreach (var element in source){
1988 min = Math.Min (selector (element), min);
1992 throw NoMatchingElement ();
1996 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1998 Check.SourceAndSelector (source, selector);
2001 var min = double.MaxValue;
2002 foreach (var element in source){
2003 min = Math.Min (selector (element), min);
2007 throw NoMatchingElement ();
2011 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2013 Check.SourceAndSelector (source, selector);
2016 var min = float.MaxValue;
2017 foreach (var element in source){
2018 min = Math.Min (selector (element), min);
2022 throw NoMatchingElement ();
2026 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2028 Check.SourceAndSelector (source, selector);
2031 var min = decimal.MaxValue;
2032 foreach (var element in source){
2033 min = Math.Min (selector (element), min);
2037 throw NoMatchingElement ();
2041 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2043 Check.SourceAndSelector (source, selector);
2047 foreach (var element in source) {
2048 int? item = selector (element);
2052 else if (item < min)
2062 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2064 Check.SourceAndSelector (source, selector);
2068 foreach (var element in source) {
2069 long? item = selector (element);
2073 else if (item < min)
2083 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2085 Check.SourceAndSelector (source, selector);
2089 foreach (var element in source) {
2090 float? item = selector (element);
2094 else if (item < min)
2104 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2106 Check.SourceAndSelector (source, selector);
2110 foreach (var element in source) {
2111 double? item = selector (element);
2115 else if (item < min)
2125 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2127 Check.SourceAndSelector (source, selector);
2130 decimal? min = null;
2131 foreach (var element in source) {
2132 decimal? item = selector (element);
2136 else if (item < min)
2146 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2148 Check.SourceAndSelector (source, selector);
2151 return source.Select (selector).Min ();
2158 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
2160 Check.Source (source);
2162 return CreateOfTypeIterator<TResult> (source);
2165 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
2167 foreach (object element in source)
2168 if (element is TResult)
2169 yield return (TResult) element;
2176 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2177 Func<TSource, TKey> keySelector)
2179 return OrderBy<TSource, TKey> (source, keySelector, null);
2182 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2183 Func<TSource, TKey> keySelector,
2184 IComparer<TKey> comparer)
2186 Check.SourceAndKeySelector (source, keySelector);
2188 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
2193 #region OrderByDescending
2195 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2196 Func<TSource, TKey> keySelector)
2198 return OrderByDescending<TSource, TKey> (source, keySelector, null);
2201 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2202 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2204 Check.SourceAndKeySelector (source, keySelector);
2206 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
2213 public static IEnumerable<int> Range (int start, int count)
2216 throw new ArgumentOutOfRangeException ("count");
2218 if (((long) start + count) - 1L > int.MaxValue)
2219 throw new ArgumentOutOfRangeException ();
2221 return CreateRangeIterator (start, count);
2224 static IEnumerable<int> CreateRangeIterator (int start, int count)
2226 for (int i = 0; i < count; i++)
2227 yield return start + i;
2234 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
2237 throw new ArgumentOutOfRangeException ();
2239 return CreateRepeatIterator (element, count);
2242 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
2244 for (int i = 0; i < count; i++)
2245 yield return element;
2252 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
2254 Check.Source (source);
2256 return CreateReverseIterator (source);
2259 static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
2261 var array = source.ToArray ();
2263 for (int i = array.Length - 1; i >= 0; i--)
2264 yield return array [i];
2271 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2273 Check.SourceAndSelector (source, selector);
2275 return CreateSelectIterator (source, selector);
2278 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
2280 foreach (var element in source)
2281 yield return selector (element);
2284 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2286 Check.SourceAndSelector (source, selector);
2288 return CreateSelectIterator (source, selector);
2291 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2294 foreach (TSource element in source) {
2295 yield return selector (element, counter);
2304 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2306 Check.SourceAndSelector (source, selector);
2308 return CreateSelectManyIterator (source, selector);
2311 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2313 foreach (TSource element in source)
2314 foreach (TResult item in selector (element))
2318 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2320 Check.SourceAndSelector (source, selector);
2322 return CreateSelectManyIterator (source, selector);
2325 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2328 foreach (TSource element in source) {
2329 foreach (TResult item in selector (element, counter))
2335 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2336 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2338 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2340 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2343 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2344 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2346 foreach (TSource element in source)
2347 foreach (TCollection collection in collectionSelector (element))
2348 yield return selector (element, collection);
2351 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2352 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2354 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2356 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2359 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2360 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2363 foreach (TSource element in source)
2364 foreach (TCollection collection in collectionSelector (element, counter++))
2365 yield return selector (element, collection);
2372 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
2375 var item = default (TSource);
2377 foreach (var element in source) {
2378 if (!predicate (element))
2382 throw MoreThanOneMatchingElement ();
2388 if (!found && fallback == Fallback.Throw)
2389 throw NoMatchingElement ();
2394 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2396 Check.Source (source);
2398 #if !FULL_AOT_RUNTIME
2399 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
2402 var item = default (TSource);
2404 foreach (var element in source) {
2406 throw MoreThanOneElement ();
2413 throw NoMatchingElement ();
2419 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2421 Check.SourceAndPredicate (source, predicate);
2423 return source.Single (predicate, Fallback.Throw);
2428 #region SingleOrDefault
2430 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2432 Check.Source (source);
2434 #if !FULL_AOT_RUNTIME
2435 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
2438 var item = default (TSource);
2440 foreach (var element in source) {
2442 throw MoreThanOneMatchingElement ();
2452 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2454 Check.SourceAndPredicate (source, predicate);
2456 return source.Single (predicate, Fallback.Default);
2463 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2465 Check.Source (source);
2467 return CreateSkipIterator (source, count);
2470 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
2472 var enumerator = source.GetEnumerator ();
2475 if (!enumerator.MoveNext ())
2478 while (enumerator.MoveNext ())
2479 yield return enumerator.Current;
2482 enumerator.Dispose ();
2490 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2492 Check.SourceAndPredicate (source, predicate);
2494 return CreateSkipWhileIterator (source, predicate);
2497 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2501 foreach (TSource element in source) {
2503 yield return element;
2505 if (!predicate (element)) {
2506 yield return element;
2512 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2514 Check.SourceAndPredicate (source, predicate);
2516 return CreateSkipWhileIterator (source, predicate);
2519 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2524 foreach (TSource element in source) {
2526 yield return element;
2528 if (!predicate (element, counter)) {
2529 yield return element;
2540 public static int Sum (this IEnumerable<int> source)
2542 Check.Source (source);
2545 foreach (var element in source)
2546 total = checked (total + element);
2550 public static int? Sum (this IEnumerable<int?> source)
2552 Check.Source (source);
2555 foreach (var element in source) {
2556 if (element.HasValue)
2557 total = checked (total + element.Value);
2562 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2564 Check.SourceAndSelector (source, selector);
2567 foreach (var element in source)
2568 total = checked (total + selector (element));
2573 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2575 Check.SourceAndSelector (source, selector);
2578 foreach (var element in source) {
2579 var value = selector (element);
2581 total = checked (total + value.Value);
2586 public static long Sum (this IEnumerable<long> source)
2588 Check.Source (source);
2592 foreach (var element in source)
2593 total = checked (total + element);
2597 public static long? Sum (this IEnumerable<long?> source)
2599 Check.Source (source);
2602 foreach (var element in source) {
2603 if (element.HasValue)
2604 total = checked (total + element.Value);
2609 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2611 Check.SourceAndSelector (source, selector);
2614 foreach (var element in source)
2615 total = checked (total + selector (element));
2619 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2621 Check.SourceAndSelector (source, selector);
2624 foreach (var element in source) {
2625 var value = selector (element);
2627 total = checked (total + value.Value);
2632 public static double Sum (this IEnumerable<double> source)
2634 Check.Source (source);
2638 foreach (var element in source)
2639 total = checked (total + element);
2643 public static double? Sum (this IEnumerable<double?> source)
2645 Check.Source (source);
2648 foreach (var element in source) {
2649 if (element.HasValue)
2650 total = checked (total + element.Value);
2655 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2657 Check.SourceAndSelector (source, selector);
2661 foreach (var element in source)
2662 total = checked (total + selector (element));
2666 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2668 Check.SourceAndSelector (source, selector);
2671 foreach (var element in source) {
2672 var value = selector (element);
2674 total = checked (total + value.Value);
2679 public static float Sum (this IEnumerable<float> source)
2681 Check.Source (source);
2685 foreach (var element in source)
2686 total = checked (total + element);
2690 public static float? Sum (this IEnumerable<float?> source)
2692 Check.Source (source);
2695 foreach (var element in source) {
2696 if (element.HasValue)
2697 total = checked (total + element.Value);
2703 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2705 Check.SourceAndSelector (source, selector);
2707 foreach (var element in source)
2708 total = checked (total + selector (element));
2712 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2714 Check.SourceAndSelector (source, selector);
2717 foreach (var element in source) {
2718 var value = selector (element);
2720 total = checked (total + value.Value);
2725 public static decimal Sum (this IEnumerable<decimal> source)
2727 Check.Source (source);
2730 foreach (var element in source)
2731 total = checked (total + element);
2735 public static decimal? Sum (this IEnumerable<decimal?> source)
2737 Check.Source (source);
2740 foreach (var element in source) {
2741 if (element.HasValue)
2742 total = checked (total + element.Value);
2748 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2750 Check.SourceAndSelector (source, selector);
2753 foreach (var element in source)
2754 total = checked (total + selector (element));
2758 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2760 Check.SourceAndSelector (source, selector);
2763 foreach (var element in source) {
2764 var value = selector (element);
2766 total = checked (total + value.Value);
2775 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2777 Check.Source (source);
2779 return CreateTakeIterator (source, count);
2782 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2788 foreach (TSource element in source) {
2789 yield return element;
2791 if (++counter == count)
2800 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2802 Check.SourceAndPredicate (source, predicate);
2804 return CreateTakeWhileIterator (source, predicate);
2807 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2809 foreach (var element in source) {
2810 if (!predicate (element))
2813 yield return element;
2817 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2819 Check.SourceAndPredicate (source, predicate);
2821 return CreateTakeWhileIterator (source, predicate);
2824 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2827 foreach (var element in source) {
2828 if (!predicate (element, counter))
2831 yield return element;
2840 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2842 return ThenBy<TSource, TKey> (source, keySelector, null);
2845 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2846 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2848 Check.SourceAndKeySelector (source, keySelector);
2850 #if FULL_AOT_RUNTIME
2851 var oe = source as OrderedEnumerable <TSource>;
2853 return oe.CreateOrderedEnumerable (keySelector, comparer, false);
2856 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2861 #region ThenByDescending
2863 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2864 Func<TSource, TKey> keySelector)
2866 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2869 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2870 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2872 Check.SourceAndKeySelector (source, keySelector);
2874 #if FULL_AOT_RUNTIME
2875 var oe = source as OrderedEnumerable <TSource>;
2877 return oe.CreateOrderedEnumerable (keySelector, comparer, true);
2879 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2886 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2888 Check.Source (source);
2891 var collection = source as ICollection<TSource>;
2892 if (collection != null) {
2893 if (collection.Count == 0)
2894 return EmptyOf<TSource>.Instance;
2896 array = new TSource [collection.Count];
2897 collection.CopyTo (array, 0);
2902 array = EmptyOf<TSource>.Instance;
2903 foreach (var element in source) {
2904 if (pos == array.Length) {
2906 array = new TSource [4];
2908 Array.Resize (ref array, pos * 2);
2911 array[pos++] = element;
2914 if (pos != array.Length)
2915 Array.Resize (ref array, pos);
2922 #region ToDictionary
2923 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2924 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2926 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2929 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2930 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2932 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2934 if (comparer == null)
2935 comparer = EqualityComparer<TKey>.Default;
2937 var dict = new Dictionary<TKey, TElement> (comparer);
2938 foreach (var e in source)
2939 dict.Add (keySelector (e), elementSelector (e));
2944 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2945 Func<TSource, TKey> keySelector)
2947 return ToDictionary (source, keySelector, null);
2950 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2951 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2953 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2959 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2961 Check.Source (source);
2963 return new List<TSource> (source);
2969 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2971 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2974 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2975 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2977 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2980 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2981 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2983 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2986 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2987 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2989 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2991 List<TElement> nullKeyElements = null;
2993 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2994 foreach (var element in source) {
2995 var key = keySelector (element);
2997 List<TElement> list;
3000 if (nullKeyElements == null)
3001 nullKeyElements = new List<TElement> ();
3003 list = nullKeyElements;
3004 } else if (!dictionary.TryGetValue (key, out list)) {
3005 list = new List<TElement> ();
3006 dictionary.Add (key, list);
3009 list.Add (elementSelector (element));
3012 return new Lookup<TKey, TElement> (dictionary, nullKeyElements);
3017 #region SequenceEqual
3019 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3021 return first.SequenceEqual (second, null);
3024 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3026 Check.FirstAndSecond (first, second);
3028 if (comparer == null)
3029 comparer = EqualityComparer<TSource>.Default;
3031 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
3032 second_enumerator = second.GetEnumerator ()) {
3034 while (first_enumerator.MoveNext ()) {
3035 if (!second_enumerator.MoveNext ())
3038 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
3042 return !second_enumerator.MoveNext ();
3050 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3052 Check.FirstAndSecond (first, second);
3054 return first.Union (second, null);
3057 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3059 Check.FirstAndSecond (first, second);
3061 if (comparer == null)
3062 comparer = EqualityComparer<TSource>.Default;
3064 return CreateUnionIterator (first, second, comparer);
3067 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3069 var items = new HashSet<TSource> (comparer);
3070 foreach (var element in first) {
3071 if (! items.Contains (element)) {
3072 items.Add (element);
3073 yield return element;
3077 foreach (var element in second) {
3078 if (! items.Contains (element)) {
3079 items.Add (element);
3080 yield return element;
3090 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
3092 Check.FirstAndSecond (first, second);
3093 if (resultSelector == null)
3094 throw new ArgumentNullException ("resultSelector");
3096 return CreateZipIterator (first, second, resultSelector);
3099 static IEnumerable<TResult> CreateZipIterator<TFirst, TSecond, TResult> (IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
3101 using (IEnumerator<TFirst> first_enumerator = first.GetEnumerator ()) {
3102 using (IEnumerator<TSecond> second_enumerator = second.GetEnumerator ()) {
3104 while (first_enumerator.MoveNext () && second_enumerator.MoveNext ()) {
3105 yield return selector (first_enumerator.Current, second_enumerator.Current);
3116 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
3118 Check.SourceAndPredicate (source, predicate);
3120 // It cannot be IList<TSource> because it may break on user implementation
3121 var array = source as TSource[];
3123 return CreateWhereIterator (array, predicate);
3125 return CreateWhereIterator (source, predicate);
3128 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
3130 foreach (TSource element in source)
3131 if (predicate (element))
3132 yield return element;
3135 static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, bool> predicate)
3137 for (int i = 0; i < source.Length; ++i) {
3138 var element = source [i];
3139 if (predicate (element))
3140 yield return element;
3144 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3146 Check.SourceAndPredicate (source, predicate);
3148 var array = source as TSource[];
3150 return CreateWhereIterator (array, predicate);
3152 return CreateWhereIterator (source, predicate);
3155 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3158 foreach (TSource element in source) {
3159 if (predicate (element, counter))
3160 yield return element;
3165 static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, int, bool> predicate)
3167 for (int i = 0; i < source.Length; ++i) {
3168 var element = source [i];
3169 if (predicate (element, i))
3170 yield return element;
3176 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
3179 return ReadOnlyCollectionOf<TSource>.Empty;
3181 var ro = source as ReadOnlyCollection<TSource>;
3185 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());
3188 #region Exception helpers
3190 static Exception EmptySequence ()
3192 return new InvalidOperationException (Locale.GetText ("Sequence contains no elements"));
3194 static Exception NoMatchingElement ()
3196 return new InvalidOperationException (Locale.GetText ("Sequence contains no matching element"));
3198 static Exception MoreThanOneElement ()
3200 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one element"));
3202 static Exception MoreThanOneMatchingElement ()
3204 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one matching element"));