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>;
747 return source.ElementAt (index, Fallback.Throw);
752 #region ElementAtOrDefault
754 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
756 Check.Source (source);
759 return default (TSource);
761 var list = source as IList<TSource>;
763 return index < list.Count ? list [index] : default (TSource);
765 return source.ElementAt (index, Fallback.Default);
772 public static IEnumerable<TResult> Empty<TResult> ()
774 return EmptyOf<TResult>.Instance;
781 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
783 return Except (first, second, null);
786 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
788 Check.FirstAndSecond (first, second);
790 if (comparer == null)
791 comparer = EqualityComparer<TSource>.Default;
793 return CreateExceptIterator (first, second, comparer);
796 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
798 var items = new HashSet<TSource> (second, comparer);
799 foreach (var element in first) {
800 if (items.Add (element))
801 yield return element;
809 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
811 foreach (var element in source)
812 if (predicate (element))
815 if (fallback == Fallback.Throw)
816 throw NoMatchingElement ();
818 return default (TSource);
821 public static TSource First<TSource> (this IEnumerable<TSource> source)
823 Check.Source (source);
825 var list = source as IList<TSource>;
830 using (var enumerator = source.GetEnumerator ()) {
831 if (enumerator.MoveNext ())
832 return enumerator.Current;
836 throw EmptySequence ();
839 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
841 Check.SourceAndPredicate (source, predicate);
843 return source.First (predicate, Fallback.Throw);
848 #region FirstOrDefault
850 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
852 Check.Source (source);
854 #if !FULL_AOT_RUNTIME
855 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
857 // inline the code to reduce dependency o generic causing AOT errors on device (e.g. bug #3285)
858 foreach (var element in source)
861 return default (TSource);
865 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
867 Check.SourceAndPredicate (source, predicate);
869 return source.First (predicate, Fallback.Default);
876 private static List<T> ContainsGroup<K, T> (
877 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
879 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
880 foreach (KeyValuePair<K, List<T>> value in items) {
881 if (comparerInUse.Equals (value.Key, key))
887 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
888 Func<TSource, TKey> keySelector)
890 return GroupBy<TSource, TKey> (source, keySelector, null);
893 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
894 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
896 Check.SourceAndKeySelector (source, keySelector);
898 return CreateGroupByIterator (source, keySelector, comparer);
901 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
902 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
904 var groups = new Dictionary<TKey, List<TSource>> ();
905 var nullList = new List<TSource> ();
907 int nullCounter = -1;
909 foreach (TSource element in source) {
910 TKey key = keySelector (element);
912 nullList.Add (element);
913 if (nullCounter == -1) {
914 nullCounter = counter;
918 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
920 group = new List<TSource> ();
921 groups.Add (key, group);
929 foreach (var group in groups) {
930 if (counter == nullCounter) {
931 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
935 yield return new Grouping<TKey, TSource> (group.Key, group.Value);
939 if (counter == nullCounter) {
940 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
945 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
946 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
948 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
951 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
952 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
954 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
956 return CreateGroupByIterator (source, keySelector, elementSelector, comparer);
959 static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement> (this IEnumerable<TSource> source,
960 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
962 var groups = new Dictionary<TKey, List<TElement>> ();
963 var nullList = new List<TElement> ();
965 int nullCounter = -1;
967 foreach (TSource item in source) {
968 TKey key = keySelector (item);
969 TElement element = elementSelector (item);
971 nullList.Add (element);
972 if (nullCounter == -1) {
973 nullCounter = counter;
977 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
979 group = new List<TElement> ();
980 groups.Add (key, group);
988 foreach (var group in groups) {
989 if (counter == nullCounter) {
990 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
994 yield return new Grouping<TKey, TElement> (group.Key, group.Value);
998 if (counter == nullCounter) {
999 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
1004 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1005 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1006 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
1008 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
1011 public static IEnumerable<TResult> GroupBy<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 Check.GroupBySelectors (source, keySelector, elementSelector, resultSelector);
1018 return CreateGroupByIterator (source, keySelector, elementSelector, resultSelector, comparer);
1021 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1022 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1023 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1024 IEqualityComparer<TKey> comparer)
1026 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
1027 source, keySelector, elementSelector, comparer);
1029 foreach (IGrouping<TKey, TElement> group in groups)
1030 yield return resultSelector (group.Key, group);
1033 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1034 Func<TSource, TKey> keySelector,
1035 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
1037 return GroupBy (source, keySelector, resultSelector, null);
1040 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1041 Func<TSource, TKey> keySelector,
1042 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1043 IEqualityComparer<TKey> comparer)
1045 Check.SourceAndKeyResultSelectors (source, keySelector, resultSelector);
1047 return CreateGroupByIterator (source, keySelector, resultSelector, comparer);
1050 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1051 Func<TSource, TKey> keySelector,
1052 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1053 IEqualityComparer<TKey> comparer)
1055 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
1057 foreach (IGrouping<TKey, TSource> group in groups)
1058 yield return resultSelector (group.Key, group);
1065 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1066 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1067 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
1069 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
1072 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1073 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1074 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1075 IEqualityComparer<TKey> comparer)
1077 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1079 if (comparer == null)
1080 comparer = EqualityComparer<TKey>.Default;
1082 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1085 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1086 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1087 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1088 IEqualityComparer<TKey> comparer)
1090 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1091 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1092 foreach (U element in inner)
1094 K innerKey = innerKeySelector (element);
1095 if (!innerKeys.ContainsKey (innerKey))
1096 innerKeys.Add (innerKey, new List<U> ());
1097 innerKeys[innerKey].Add (element);
1100 foreach (TOuter element in outer) {
1101 TKey outerKey = outerKeySelector (element);
1102 if (innerKeys.Contains (outerKey))
1103 yield return resultSelector (element, innerKeys [outerKey]);
1105 yield return resultSelector (element, Empty<TInner> ());
1113 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
1115 return Intersect (first, second, null);
1118 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1120 Check.FirstAndSecond (first, second);
1122 if (comparer == null)
1123 comparer = EqualityComparer<TSource>.Default;
1125 return CreateIntersectIterator (first, second, comparer);
1128 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1130 var items = new HashSet<TSource> (second, comparer);
1131 foreach (TSource element in first) {
1132 if (items.Remove (element))
1133 yield return element;
1141 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1142 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1143 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1145 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1147 if (comparer == null)
1148 comparer = EqualityComparer<TKey>.Default;
1150 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1153 static IEnumerable<TResult> CreateJoinIterator<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 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1158 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1159 foreach (U element in inner)
1161 K innerKey = innerKeySelector (element);
1162 if (!innerKeys.ContainsKey (innerKey))
1163 innerKeys.Add (innerKey, new List<U> ());
1164 innerKeys[innerKey].Add (element);
1167 foreach (TOuter element in outer) {
1168 TKey outerKey = outerKeySelector (element);
1169 if (innerKeys.Contains (outerKey)) {
1170 foreach (TInner innerElement in innerKeys [outerKey])
1171 yield return resultSelector (element, innerElement);
1176 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1177 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1178 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
1180 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
1187 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1190 var item = default (TSource);
1192 foreach (var element in source) {
1193 if (!predicate (element))
1203 if (fallback == Fallback.Throw)
1204 throw NoMatchingElement ();
1209 public static TSource Last<TSource> (this IEnumerable<TSource> source)
1211 Check.Source (source);
1213 var collection = source as ICollection<TSource>;
1214 if (collection != null && collection.Count == 0)
1215 throw EmptySequence ();
1217 var list = source as IList<TSource>;
1219 return list [list.Count - 1];
1221 #if !FULL_AOT_RUNTIME
1222 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
1225 var item = default (TSource);
1227 foreach (var element in source) {
1235 throw EmptySequence ();
1239 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1241 Check.SourceAndPredicate (source, predicate);
1243 return source.Last (predicate, Fallback.Throw);
1248 #region LastOrDefault
1250 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
1252 Check.Source (source);
1254 var list = source as IList<TSource>;
1256 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
1258 #if !FULL_AOT_RUNTIME
1259 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
1262 var item = default (TSource);
1264 foreach (var element in source) {
1276 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1278 Check.SourceAndPredicate (source, predicate);
1280 return source.Last (predicate, Fallback.Default);
1287 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1289 Check.Source (source);
1292 var array = source as TSource [];
1294 return array.LongLength;
1298 using (var enumerator = source.GetEnumerator ())
1299 while (enumerator.MoveNext ())
1305 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1307 Check.SourceAndSelector (source, predicate);
1310 foreach (TSource element in source)
1311 if (predicate (element))
1321 public static int Max (this IEnumerable<int> source)
1323 Check.Source (source);
1326 var max = int.MinValue;
1327 foreach (var element in source){
1328 max = Math.Max (element, max);
1332 throw EmptySequence();
1336 public static long Max (this IEnumerable<long> source)
1338 Check.Source (source);
1341 var max = long.MinValue;
1342 foreach (var element in source){
1343 max = Math.Max (element, max);
1347 throw EmptySequence ();
1351 public static double Max (this IEnumerable<double> source)
1353 Check.Source (source);
1356 var max = double.MinValue;
1357 foreach (var element in source){
1358 max = Math.Max (element, max);
1362 throw EmptySequence ();
1366 public static float Max (this IEnumerable<float> source)
1368 Check.Source (source);
1371 var max = float.MinValue;
1372 foreach (var element in source){
1373 max = Math.Max (element, max);
1377 throw EmptySequence ();
1381 public static decimal Max (this IEnumerable<decimal> source)
1383 Check.Source (source);
1386 var max = decimal.MinValue;
1387 foreach (var element in source){
1388 max = Math.Max (element, max);
1392 throw EmptySequence ();
1396 public static int? Max (this IEnumerable<int?> source)
1398 Check.Source (source);
1401 var max = int.MinValue;
1403 foreach (var element in source) {
1404 if (!element.HasValue)
1407 max = Math.Max (element.Value, max);
1417 public static long? Max (this IEnumerable<long?> source)
1419 Check.Source (source);
1422 var max = long.MinValue;
1424 foreach (var element in source) {
1425 if (!element.HasValue)
1428 max = Math.Max (element.Value, max);
1438 public static double? Max (this IEnumerable<double?> source)
1440 Check.Source (source);
1443 var max = double.MinValue;
1445 foreach (var element in source) {
1446 if (!element.HasValue)
1449 max = Math.Max (element.Value, max);
1459 public static float? Max (this IEnumerable<float?> source)
1461 Check.Source (source);
1464 var max = float.MinValue;
1466 foreach (var element in source) {
1467 if (!element.HasValue)
1470 max = Math.Max (element.Value, max);
1480 public static decimal? Max (this IEnumerable<decimal?> source)
1482 Check.Source (source);
1485 var max = decimal.MinValue;
1487 foreach (var element in source) {
1488 if (!element.HasValue)
1491 max = Math.Max (element.Value, max);
1501 // TODO: test nullable and non-nullable
1502 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1504 Check.Source (source);
1506 var comparer = Comparer<TSource>.Default;
1508 TSource max = default (TSource);
1510 if (default (TSource) == null){
1511 foreach (var element in source) {
1512 if (element == null)
1515 if (max == null || comparer.Compare (element, max) > 0)
1520 foreach (var element in source) {
1526 if (comparer.Compare (element, max) > 0)
1530 throw EmptySequence ();
1535 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1537 Check.SourceAndSelector (source, selector);
1540 var max = int.MinValue;
1541 foreach (var element in source){
1542 max = Math.Max (selector (element), max);
1546 throw NoMatchingElement ();
1550 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1552 Check.SourceAndSelector (source, selector);
1555 var max = long.MinValue;
1556 foreach (var element in source){
1557 max = Math.Max (selector (element), max);
1561 throw NoMatchingElement ();
1565 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1567 Check.SourceAndSelector (source, selector);
1570 var max = double.MinValue;
1571 foreach (var element in source){
1572 max = Math.Max (selector (element), max);
1576 throw NoMatchingElement ();
1580 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1582 Check.SourceAndSelector (source, selector);
1585 var max = float.MinValue;
1586 foreach (var element in source){
1587 max = Math.Max (selector (element), max);
1591 throw NoMatchingElement ();
1595 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1597 Check.SourceAndSelector (source, selector);
1600 var max = decimal.MinValue;
1601 foreach (var element in source){
1602 max = Math.Max (selector (element), max);
1606 throw NoMatchingElement ();
1610 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1613 foreach (var element in source) {
1614 initValue = selector (element, initValue);
1619 throw NoMatchingElement ();
1624 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1626 Check.SourceAndSelector (source, selector);
1630 foreach (var element in source) {
1631 int? item = selector (element);
1635 else if (item > max)
1645 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1647 Check.SourceAndSelector (source, selector);
1651 foreach (var element in source) {
1652 long? item = selector (element);
1656 else if (item > max)
1666 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1668 Check.SourceAndSelector (source, selector);
1672 foreach (var element in source) {
1673 double? item = selector (element);
1677 else if (item > max)
1687 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1689 Check.SourceAndSelector (source, selector);
1693 foreach (var element in source) {
1694 float? item = selector (element);
1698 else if (item > max)
1708 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1710 Check.SourceAndSelector (source, selector);
1713 decimal? max = null;
1714 foreach (var element in source) {
1715 decimal? item = selector (element);
1719 else if (item > max)
1729 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1731 Check.SourceAndSelector (source, selector);
1734 return source.Select (selector).Max ();
1741 public static int Min (this IEnumerable<int> source)
1743 Check.Source (source);
1746 var min = int.MaxValue;
1747 foreach (var element in source){
1748 min = Math.Min (element, min);
1752 throw EmptySequence ();
1756 public static long Min (this IEnumerable<long> source)
1758 Check.Source (source);
1761 var min = long.MaxValue;
1762 foreach (var element in source){
1763 min = Math.Min (element, min);
1767 throw EmptySequence ();
1771 public static double Min (this IEnumerable<double> source)
1773 Check.Source (source);
1776 var min = double.MaxValue;
1777 foreach (var element in source){
1778 min = Math.Min (element, min);
1782 throw EmptySequence ();
1786 public static float Min (this IEnumerable<float> source)
1788 Check.Source (source);
1791 var min = float.MaxValue;
1792 foreach (var element in source){
1793 min = Math.Min (element, min);
1797 throw EmptySequence ();
1801 public static decimal Min (this IEnumerable<decimal> source)
1803 Check.Source (source);
1806 var min = decimal.MaxValue;
1807 foreach (var element in source){
1808 min = Math.Min (element, min);
1812 throw EmptySequence ();
1816 public static int? Min (this IEnumerable<int?> source)
1818 Check.Source (source);
1821 var min = int.MaxValue;
1823 foreach (var element in source) {
1824 if (!element.HasValue)
1827 min = Math.Min (element.Value, min);
1837 public static long? Min (this IEnumerable<long?> source)
1839 Check.Source (source);
1842 var min = long.MaxValue;
1844 foreach (var element in source) {
1845 if (!element.HasValue)
1848 min = Math.Min (element.Value, min);
1858 public static double? Min (this IEnumerable<double?> source)
1860 Check.Source (source);
1863 var min = double.MaxValue;
1865 foreach (var element in source) {
1866 if (!element.HasValue)
1869 min = Math.Min (element.Value, min);
1879 public static float? Min (this IEnumerable<float?> source)
1881 Check.Source (source);
1884 var min = float.MaxValue;
1886 foreach (var element in source) {
1887 if (!element.HasValue)
1890 min = Math.Min (element.Value, min);
1900 public static decimal? Min (this IEnumerable<decimal?> source)
1902 Check.Source (source);
1905 var min = decimal.MaxValue;
1907 foreach (var element in source) {
1908 if (!element.HasValue)
1911 min = Math.Min (element.Value, min);
1921 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1923 Check.Source (source);
1925 var comparer = Comparer<TSource>.Default;
1927 TSource min = default (TSource);
1929 if (default (TSource) == null){
1930 foreach (var element in source) {
1931 if (element == null)
1934 if (min == null || comparer.Compare (element, min) < 0)
1939 foreach (var element in source) {
1945 if (comparer.Compare (element, min) < 0)
1949 throw EmptySequence ();
1954 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1956 Check.SourceAndSelector (source, selector);
1959 var min = int.MaxValue;
1960 foreach (var element in source){
1961 min = Math.Min (selector (element), min);
1965 throw NoMatchingElement ();
1969 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1971 Check.SourceAndSelector (source, selector);
1974 var min = long.MaxValue;
1975 foreach (var element in source){
1976 min = Math.Min (selector (element), min);
1980 throw NoMatchingElement ();
1984 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1986 Check.SourceAndSelector (source, selector);
1989 var min = double.MaxValue;
1990 foreach (var element in source){
1991 min = Math.Min (selector (element), min);
1995 throw NoMatchingElement ();
1999 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2001 Check.SourceAndSelector (source, selector);
2004 var min = float.MaxValue;
2005 foreach (var element in source){
2006 min = Math.Min (selector (element), min);
2010 throw NoMatchingElement ();
2014 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2016 Check.SourceAndSelector (source, selector);
2019 var min = decimal.MaxValue;
2020 foreach (var element in source){
2021 min = Math.Min (selector (element), min);
2025 throw NoMatchingElement ();
2029 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2031 Check.SourceAndSelector (source, selector);
2035 foreach (var element in source) {
2036 int? item = selector (element);
2040 else if (item < min)
2050 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2052 Check.SourceAndSelector (source, selector);
2056 foreach (var element in source) {
2057 long? item = selector (element);
2061 else if (item < min)
2071 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2073 Check.SourceAndSelector (source, selector);
2077 foreach (var element in source) {
2078 float? item = selector (element);
2082 else if (item < min)
2092 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2094 Check.SourceAndSelector (source, selector);
2098 foreach (var element in source) {
2099 double? item = selector (element);
2103 else if (item < min)
2113 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2115 Check.SourceAndSelector (source, selector);
2118 decimal? min = null;
2119 foreach (var element in source) {
2120 decimal? item = selector (element);
2124 else if (item < min)
2134 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2136 Check.SourceAndSelector (source, selector);
2139 return source.Select (selector).Min ();
2146 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
2148 Check.Source (source);
2150 return CreateOfTypeIterator<TResult> (source);
2153 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
2155 foreach (object element in source)
2156 if (element is TResult)
2157 yield return (TResult) element;
2164 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2165 Func<TSource, TKey> keySelector)
2167 return OrderBy<TSource, TKey> (source, keySelector, null);
2170 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2171 Func<TSource, TKey> keySelector,
2172 IComparer<TKey> comparer)
2174 Check.SourceAndKeySelector (source, keySelector);
2176 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
2181 #region OrderByDescending
2183 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2184 Func<TSource, TKey> keySelector)
2186 return OrderByDescending<TSource, TKey> (source, keySelector, null);
2189 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2190 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2192 Check.SourceAndKeySelector (source, keySelector);
2194 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
2201 public static IEnumerable<int> Range (int start, int count)
2204 throw new ArgumentOutOfRangeException ("count");
2206 if (((long) start + count) - 1L > int.MaxValue)
2207 throw new ArgumentOutOfRangeException ();
2209 return CreateRangeIterator (start, count);
2212 static IEnumerable<int> CreateRangeIterator (int start, int count)
2214 for (int i = 0; i < count; i++)
2215 yield return start + i;
2222 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
2225 throw new ArgumentOutOfRangeException ();
2227 return CreateRepeatIterator (element, count);
2230 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
2232 for (int i = 0; i < count; i++)
2233 yield return element;
2240 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
2242 Check.Source (source);
2244 return CreateReverseIterator (source);
2247 static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
2249 var array = source.ToArray ();
2251 for (int i = array.Length - 1; i >= 0; i--)
2252 yield return array [i];
2259 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2261 Check.SourceAndSelector (source, selector);
2263 return CreateSelectIterator (source, selector);
2266 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
2268 foreach (var element in source)
2269 yield return selector (element);
2272 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2274 Check.SourceAndSelector (source, selector);
2276 return CreateSelectIterator (source, selector);
2279 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2282 foreach (TSource element in source) {
2283 yield return selector (element, counter);
2292 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2294 Check.SourceAndSelector (source, selector);
2296 return CreateSelectManyIterator (source, selector);
2299 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2301 foreach (TSource element in source)
2302 foreach (TResult item in selector (element))
2306 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2308 Check.SourceAndSelector (source, selector);
2310 return CreateSelectManyIterator (source, selector);
2313 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2316 foreach (TSource element in source) {
2317 foreach (TResult item in selector (element, counter))
2323 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2324 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2326 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2328 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2331 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2332 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2334 foreach (TSource element in source)
2335 foreach (TCollection collection in collectionSelector (element))
2336 yield return selector (element, collection);
2339 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2340 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2342 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2344 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2347 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2348 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2351 foreach (TSource element in source)
2352 foreach (TCollection collection in collectionSelector (element, counter++))
2353 yield return selector (element, collection);
2360 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
2363 var item = default (TSource);
2365 foreach (var element in source) {
2366 if (!predicate (element))
2370 throw MoreThanOneMatchingElement ();
2376 if (!found && fallback == Fallback.Throw)
2377 throw NoMatchingElement ();
2382 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2384 Check.Source (source);
2386 #if !FULL_AOT_RUNTIME
2387 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
2390 var item = default (TSource);
2392 foreach (var element in source) {
2394 throw MoreThanOneElement ();
2401 throw NoMatchingElement ();
2407 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2409 Check.SourceAndPredicate (source, predicate);
2411 return source.Single (predicate, Fallback.Throw);
2416 #region SingleOrDefault
2418 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2420 Check.Source (source);
2422 #if !FULL_AOT_RUNTIME
2423 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
2426 var item = default (TSource);
2428 foreach (var element in source) {
2430 throw MoreThanOneMatchingElement ();
2440 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2442 Check.SourceAndPredicate (source, predicate);
2444 return source.Single (predicate, Fallback.Default);
2451 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2453 Check.Source (source);
2455 return CreateSkipIterator (source, count);
2458 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
2460 var enumerator = source.GetEnumerator ();
2463 if (!enumerator.MoveNext ())
2466 while (enumerator.MoveNext ())
2467 yield return enumerator.Current;
2470 enumerator.Dispose ();
2478 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2480 Check.SourceAndPredicate (source, predicate);
2482 return CreateSkipWhileIterator (source, predicate);
2485 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2489 foreach (TSource element in source) {
2491 yield return element;
2493 if (!predicate (element)) {
2494 yield return element;
2500 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2502 Check.SourceAndPredicate (source, predicate);
2504 return CreateSkipWhileIterator (source, predicate);
2507 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2512 foreach (TSource element in source) {
2514 yield return element;
2516 if (!predicate (element, counter)) {
2517 yield return element;
2528 public static int Sum (this IEnumerable<int> source)
2530 Check.Source (source);
2533 foreach (var element in source)
2534 total = checked (total + element);
2538 public static int? Sum (this IEnumerable<int?> source)
2540 Check.Source (source);
2543 foreach (var element in source) {
2544 if (element.HasValue)
2545 total = checked (total + element.Value);
2550 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2552 Check.SourceAndSelector (source, selector);
2555 foreach (var element in source)
2556 total = checked (total + selector (element));
2561 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2563 Check.SourceAndSelector (source, selector);
2566 foreach (var element in source) {
2567 var value = selector (element);
2569 total = checked (total + value.Value);
2574 public static long Sum (this IEnumerable<long> source)
2576 Check.Source (source);
2580 foreach (var element in source)
2581 total = checked (total + element);
2585 public static long? Sum (this IEnumerable<long?> source)
2587 Check.Source (source);
2590 foreach (var element in source) {
2591 if (element.HasValue)
2592 total = checked (total + element.Value);
2597 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2599 Check.SourceAndSelector (source, selector);
2602 foreach (var element in source)
2603 total = checked (total + selector (element));
2607 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2609 Check.SourceAndSelector (source, selector);
2612 foreach (var element in source) {
2613 var value = selector (element);
2615 total = checked (total + value.Value);
2620 public static double Sum (this IEnumerable<double> source)
2622 Check.Source (source);
2626 foreach (var element in source)
2627 total = checked (total + element);
2631 public static double? Sum (this IEnumerable<double?> source)
2633 Check.Source (source);
2636 foreach (var element in source) {
2637 if (element.HasValue)
2638 total = checked (total + element.Value);
2643 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2645 Check.SourceAndSelector (source, selector);
2649 foreach (var element in source)
2650 total = checked (total + selector (element));
2654 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2656 Check.SourceAndSelector (source, selector);
2659 foreach (var element in source) {
2660 var value = selector (element);
2662 total = checked (total + value.Value);
2667 public static float Sum (this IEnumerable<float> source)
2669 Check.Source (source);
2673 foreach (var element in source)
2674 total = checked (total + element);
2678 public static float? Sum (this IEnumerable<float?> source)
2680 Check.Source (source);
2683 foreach (var element in source) {
2684 if (element.HasValue)
2685 total = checked (total + element.Value);
2691 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2693 Check.SourceAndSelector (source, selector);
2695 foreach (var element in source)
2696 total = checked (total + selector (element));
2700 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2702 Check.SourceAndSelector (source, selector);
2705 foreach (var element in source) {
2706 var value = selector (element);
2708 total = checked (total + value.Value);
2713 public static decimal Sum (this IEnumerable<decimal> source)
2715 Check.Source (source);
2718 foreach (var element in source)
2719 total = checked (total + element);
2723 public static decimal? Sum (this IEnumerable<decimal?> source)
2725 Check.Source (source);
2728 foreach (var element in source) {
2729 if (element.HasValue)
2730 total = checked (total + element.Value);
2736 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2738 Check.SourceAndSelector (source, selector);
2741 foreach (var element in source)
2742 total = checked (total + selector (element));
2746 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2748 Check.SourceAndSelector (source, selector);
2751 foreach (var element in source) {
2752 var value = selector (element);
2754 total = checked (total + value.Value);
2763 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2765 Check.Source (source);
2767 return CreateTakeIterator (source, count);
2770 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2776 foreach (TSource element in source) {
2777 yield return element;
2779 if (++counter == count)
2788 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2790 Check.SourceAndPredicate (source, predicate);
2792 return CreateTakeWhileIterator (source, predicate);
2795 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2797 foreach (var element in source) {
2798 if (!predicate (element))
2801 yield return element;
2805 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2807 Check.SourceAndPredicate (source, predicate);
2809 return CreateTakeWhileIterator (source, predicate);
2812 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2815 foreach (var element in source) {
2816 if (!predicate (element, counter))
2819 yield return element;
2828 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2830 return ThenBy<TSource, TKey> (source, keySelector, null);
2833 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2834 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2836 Check.SourceAndKeySelector (source, keySelector);
2838 #if FULL_AOT_RUNTIME
2839 var oe = source as OrderedEnumerable <TSource>;
2841 return oe.CreateOrderedEnumerable (keySelector, comparer, false);
2844 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2849 #region ThenByDescending
2851 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2852 Func<TSource, TKey> keySelector)
2854 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2857 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2858 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2860 Check.SourceAndKeySelector (source, keySelector);
2862 #if FULL_AOT_RUNTIME
2863 var oe = source as OrderedEnumerable <TSource>;
2865 return oe.CreateOrderedEnumerable (keySelector, comparer, true);
2867 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2874 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2876 Check.Source (source);
2879 var collection = source as ICollection<TSource>;
2880 if (collection != null) {
2881 if (collection.Count == 0)
2882 return EmptyOf<TSource>.Instance;
2884 array = new TSource [collection.Count];
2885 collection.CopyTo (array, 0);
2890 array = EmptyOf<TSource>.Instance;
2891 foreach (var element in source) {
2892 if (pos == array.Length) {
2894 array = new TSource [4];
2896 Array.Resize (ref array, pos * 2);
2899 array[pos++] = element;
2902 if (pos != array.Length)
2903 Array.Resize (ref array, pos);
2910 #region ToDictionary
2911 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2912 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2914 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2917 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2918 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2920 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2922 if (comparer == null)
2923 comparer = EqualityComparer<TKey>.Default;
2925 var dict = new Dictionary<TKey, TElement> (comparer);
2926 foreach (var e in source)
2927 dict.Add (keySelector (e), elementSelector (e));
2932 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2933 Func<TSource, TKey> keySelector)
2935 return ToDictionary (source, keySelector, null);
2938 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2939 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2941 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2947 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2949 Check.Source (source);
2951 return new List<TSource> (source);
2957 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2959 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2962 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2963 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2965 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2968 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2969 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2971 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2974 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2975 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2977 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2979 List<TElement> nullKeyElements = null;
2981 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2982 foreach (var element in source) {
2983 var key = keySelector (element);
2985 List<TElement> list;
2988 if (nullKeyElements == null)
2989 nullKeyElements = new List<TElement> ();
2991 list = nullKeyElements;
2992 } else if (!dictionary.TryGetValue (key, out list)) {
2993 list = new List<TElement> ();
2994 dictionary.Add (key, list);
2997 list.Add (elementSelector (element));
3000 return new Lookup<TKey, TElement> (dictionary, nullKeyElements);
3005 #region SequenceEqual
3007 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3009 return first.SequenceEqual (second, null);
3012 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3014 Check.FirstAndSecond (first, second);
3016 if (comparer == null)
3017 comparer = EqualityComparer<TSource>.Default;
3019 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
3020 second_enumerator = second.GetEnumerator ()) {
3022 while (first_enumerator.MoveNext ()) {
3023 if (!second_enumerator.MoveNext ())
3026 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
3030 return !second_enumerator.MoveNext ();
3038 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3040 Check.FirstAndSecond (first, second);
3042 return first.Union (second, null);
3045 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3047 Check.FirstAndSecond (first, second);
3049 if (comparer == null)
3050 comparer = EqualityComparer<TSource>.Default;
3052 return CreateUnionIterator (first, second, comparer);
3055 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3057 var items = new HashSet<TSource> (comparer);
3058 foreach (var element in first) {
3059 if (! items.Contains (element)) {
3060 items.Add (element);
3061 yield return element;
3065 foreach (var element in second) {
3066 if (! items.Contains (element)) {
3067 items.Add (element);
3068 yield return element;
3075 #if NET_4_0 || MOONLIGHT || MOBILE
3078 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
3080 Check.FirstAndSecond (first, second);
3081 if (resultSelector == null)
3082 throw new ArgumentNullException ("resultSelector");
3084 return CreateZipIterator (first, second, resultSelector);
3087 static IEnumerable<TResult> CreateZipIterator<TFirst, TSecond, TResult> (IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
3089 using (IEnumerator<TFirst> first_enumerator = first.GetEnumerator ()) {
3090 using (IEnumerator<TSecond> second_enumerator = second.GetEnumerator ()) {
3092 while (first_enumerator.MoveNext () && second_enumerator.MoveNext ()) {
3093 yield return selector (first_enumerator.Current, second_enumerator.Current);
3104 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
3106 Check.SourceAndPredicate (source, predicate);
3108 return CreateWhereIterator (source, predicate);
3111 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
3113 foreach (TSource element in source)
3114 if (predicate (element))
3115 yield return element;
3118 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3120 Check.SourceAndPredicate (source, predicate);
3122 return CreateWhereIterator (source, predicate);
3125 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3128 foreach (TSource element in source) {
3129 if (predicate (element, counter))
3130 yield return element;
3137 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
3140 return ReadOnlyCollectionOf<TSource>.Empty;
3142 var ro = source as ReadOnlyCollection<TSource>;
3146 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());
3149 #region Exception helpers
3151 static Exception EmptySequence ()
3153 return new InvalidOperationException (Locale.GetText ("Sequence contains no elements"));
3155 static Exception NoMatchingElement ()
3157 return new InvalidOperationException (Locale.GetText ("Sequence contains no matching element"));
3159 static Exception MoreThanOneElement ()
3161 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one element"));
3163 static Exception MoreThanOneMatchingElement ()
3165 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one matching element"));