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 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
889 Func<TSource, TKey> keySelector)
891 return GroupBy<TSource, TKey> (source, keySelector, null);
894 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
895 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
897 Check.SourceAndKeySelector (source, keySelector);
899 return CreateGroupByIterator (source, keySelector, comparer);
902 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
903 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
905 var groups = new Dictionary<TKey, List<TSource>> (comparer);
906 var nullList = new List<TSource> ();
908 int nullCounter = -1;
910 foreach (TSource element in source) {
911 TKey key = keySelector (element);
913 nullList.Add (element);
914 if (nullCounter == -1) {
915 nullCounter = counter;
920 if (!groups.TryGetValue (key, out group)) {
921 group = new List<TSource> ();
922 groups.Add (key, group);
930 foreach (var group in groups) {
931 if (counter == nullCounter) {
932 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
936 yield return new Grouping<TKey, TSource> (group.Key, group.Value);
940 if (counter == nullCounter) {
941 yield return new Grouping<TKey, TSource> (default (TKey), nullList);
946 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
947 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
949 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
952 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
953 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
955 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
957 return CreateGroupByIterator (source, keySelector, elementSelector, comparer);
960 static IEnumerable<IGrouping<TKey, TElement>> CreateGroupByIterator<TSource, TKey, TElement> (this IEnumerable<TSource> source,
961 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
963 var groups = new Dictionary<TKey, List<TElement>> (comparer);
964 var nullList = new List<TElement> ();
966 int nullCounter = -1;
968 foreach (TSource item in source) {
969 TKey key = keySelector (item);
970 TElement element = elementSelector (item);
972 nullList.Add (element);
973 if (nullCounter == -1) {
974 nullCounter = counter;
978 List<TElement> group;
979 if (!groups.TryGetValue (key, out group)) {
980 group = new List<TElement> ();
981 groups.Add (key, group);
989 foreach (var group in groups) {
990 if (counter == nullCounter) {
991 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
995 yield return new Grouping<TKey, TElement> (group.Key, group.Value);
999 if (counter == nullCounter) {
1000 yield return new Grouping<TKey, TElement> (default (TKey), nullList);
1005 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1006 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1007 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
1009 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
1012 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1013 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1014 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1015 IEqualityComparer<TKey> comparer)
1017 Check.GroupBySelectors (source, keySelector, elementSelector, resultSelector);
1019 return CreateGroupByIterator (source, keySelector, elementSelector, resultSelector, comparer);
1022 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
1023 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
1024 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1025 IEqualityComparer<TKey> comparer)
1027 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
1028 source, keySelector, elementSelector, comparer);
1030 foreach (IGrouping<TKey, TElement> group in groups)
1031 yield return resultSelector (group.Key, group);
1034 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1035 Func<TSource, TKey> keySelector,
1036 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
1038 return GroupBy (source, keySelector, resultSelector, null);
1041 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1042 Func<TSource, TKey> keySelector,
1043 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1044 IEqualityComparer<TKey> comparer)
1046 Check.SourceAndKeyResultSelectors (source, keySelector, resultSelector);
1048 return CreateGroupByIterator (source, keySelector, resultSelector, comparer);
1051 static IEnumerable<TResult> CreateGroupByIterator<TSource, TKey, TResult> (this IEnumerable<TSource> source,
1052 Func<TSource, TKey> keySelector,
1053 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1054 IEqualityComparer<TKey> comparer)
1056 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
1058 foreach (IGrouping<TKey, TSource> group in groups)
1059 yield return resultSelector (group.Key, group);
1066 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1067 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1068 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
1070 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
1073 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1074 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1075 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1076 IEqualityComparer<TKey> comparer)
1078 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1080 if (comparer == null)
1081 comparer = EqualityComparer<TKey>.Default;
1083 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1086 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1087 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1088 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1089 IEqualityComparer<TKey> comparer)
1091 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1092 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1093 foreach (U element in inner)
1095 K innerKey = innerKeySelector (element);
1096 if (!innerKeys.ContainsKey (innerKey))
1097 innerKeys.Add (innerKey, new List<U> ());
1098 innerKeys[innerKey].Add (element);
1101 foreach (TOuter element in outer) {
1102 TKey outerKey = outerKeySelector (element);
1103 if (outerKey != null && innerKeys.Contains (outerKey))
1104 yield return resultSelector (element, innerKeys [outerKey]);
1106 yield return resultSelector (element, Empty<TInner> ());
1114 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
1116 return Intersect (first, second, null);
1119 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1121 Check.FirstAndSecond (first, second);
1123 if (comparer == null)
1124 comparer = EqualityComparer<TSource>.Default;
1126 return CreateIntersectIterator (first, second, comparer);
1129 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
1131 var items = new HashSet<TSource> (second, comparer);
1132 foreach (TSource element in first) {
1133 if (items.Remove (element))
1134 yield return element;
1142 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1143 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1144 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1146 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1148 if (comparer == null)
1149 comparer = EqualityComparer<TKey>.Default;
1151 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
1154 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1155 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1156 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
1158 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
1159 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
1160 foreach (U element in inner)
1162 K innerKey = innerKeySelector (element);
1163 if (!innerKeys.ContainsKey (innerKey))
1164 innerKeys.Add (innerKey, new List<U> ());
1165 innerKeys[innerKey].Add (element);
1168 foreach (TOuter element in outer) {
1169 TKey outerKey = outerKeySelector (element);
1170 if (outerKey != null && innerKeys.Contains (outerKey)) {
1171 foreach (TInner innerElement in innerKeys [outerKey])
1172 yield return resultSelector (element, innerElement);
1177 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
1178 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1179 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
1181 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
1188 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1191 var item = default (TSource);
1193 foreach (var element in source) {
1194 if (!predicate (element))
1204 if (fallback == Fallback.Throw)
1205 throw NoMatchingElement ();
1210 public static TSource Last<TSource> (this IEnumerable<TSource> source)
1212 Check.Source (source);
1214 var collection = source as ICollection<TSource>;
1215 if (collection != null && collection.Count == 0)
1216 throw EmptySequence ();
1218 var list = source as IList<TSource>;
1220 return list [list.Count - 1];
1222 #if !FULL_AOT_RUNTIME
1223 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
1226 var item = default (TSource);
1228 foreach (var element in source) {
1236 throw EmptySequence ();
1240 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1242 Check.SourceAndPredicate (source, predicate);
1244 return source.Last (predicate, Fallback.Throw);
1249 #region LastOrDefault
1251 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
1253 Check.Source (source);
1255 var list = source as IList<TSource>;
1257 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
1259 #if !FULL_AOT_RUNTIME
1260 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
1263 var item = default (TSource);
1265 foreach (var element in source) {
1277 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1279 Check.SourceAndPredicate (source, predicate);
1281 return source.Last (predicate, Fallback.Default);
1288 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1290 Check.Source (source);
1293 var array = source as TSource [];
1295 return array.LongLength;
1299 using (var enumerator = source.GetEnumerator ())
1300 while (enumerator.MoveNext ())
1306 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1308 Check.SourceAndSelector (source, predicate);
1311 foreach (TSource element in source)
1312 if (predicate (element))
1322 public static int Max (this IEnumerable<int> source)
1324 Check.Source (source);
1327 var max = int.MinValue;
1328 foreach (var element in source){
1329 max = Math.Max (element, max);
1333 throw EmptySequence();
1337 public static long Max (this IEnumerable<long> source)
1339 Check.Source (source);
1342 var max = long.MinValue;
1343 foreach (var element in source){
1344 max = Math.Max (element, max);
1348 throw EmptySequence ();
1352 public static double Max (this IEnumerable<double> source)
1354 Check.Source (source);
1357 var max = double.MinValue;
1358 foreach (var element in source){
1359 max = Math.Max (element, max);
1363 throw EmptySequence ();
1367 public static float Max (this IEnumerable<float> source)
1369 Check.Source (source);
1372 var max = float.MinValue;
1373 foreach (var element in source){
1374 max = Math.Max (element, max);
1378 throw EmptySequence ();
1382 public static decimal Max (this IEnumerable<decimal> source)
1384 Check.Source (source);
1387 var max = decimal.MinValue;
1388 foreach (var element in source){
1389 max = Math.Max (element, max);
1393 throw EmptySequence ();
1397 public static int? Max (this IEnumerable<int?> source)
1399 Check.Source (source);
1402 var max = int.MinValue;
1404 foreach (var element in source) {
1405 if (!element.HasValue)
1408 max = Math.Max (element.Value, max);
1418 public static long? Max (this IEnumerable<long?> source)
1420 Check.Source (source);
1423 var max = long.MinValue;
1425 foreach (var element in source) {
1426 if (!element.HasValue)
1429 max = Math.Max (element.Value, max);
1439 public static double? Max (this IEnumerable<double?> source)
1441 Check.Source (source);
1444 var max = double.MinValue;
1446 foreach (var element in source) {
1447 if (!element.HasValue)
1450 max = Math.Max (element.Value, max);
1460 public static float? Max (this IEnumerable<float?> source)
1462 Check.Source (source);
1465 var max = float.MinValue;
1467 foreach (var element in source) {
1468 if (!element.HasValue)
1471 max = Math.Max (element.Value, max);
1481 public static decimal? Max (this IEnumerable<decimal?> source)
1483 Check.Source (source);
1486 var max = decimal.MinValue;
1488 foreach (var element in source) {
1489 if (!element.HasValue)
1492 max = Math.Max (element.Value, max);
1502 // TODO: test nullable and non-nullable
1503 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1505 Check.Source (source);
1507 var comparer = Comparer<TSource>.Default;
1509 TSource max = default (TSource);
1511 if (default (TSource) == null){
1512 foreach (var element in source) {
1513 if (element == null)
1516 if (max == null || comparer.Compare (element, max) > 0)
1521 foreach (var element in source) {
1527 if (comparer.Compare (element, max) > 0)
1531 throw EmptySequence ();
1536 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1538 Check.SourceAndSelector (source, selector);
1541 var max = int.MinValue;
1542 foreach (var element in source){
1543 max = Math.Max (selector (element), max);
1547 throw NoMatchingElement ();
1551 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1553 Check.SourceAndSelector (source, selector);
1556 var max = long.MinValue;
1557 foreach (var element in source){
1558 max = Math.Max (selector (element), max);
1562 throw NoMatchingElement ();
1566 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1568 Check.SourceAndSelector (source, selector);
1571 var max = double.MinValue;
1572 foreach (var element in source){
1573 max = Math.Max (selector (element), max);
1577 throw NoMatchingElement ();
1581 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1583 Check.SourceAndSelector (source, selector);
1586 var max = float.MinValue;
1587 foreach (var element in source){
1588 max = Math.Max (selector (element), max);
1592 throw NoMatchingElement ();
1596 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1598 Check.SourceAndSelector (source, selector);
1601 var max = decimal.MinValue;
1602 foreach (var element in source){
1603 max = Math.Max (selector (element), max);
1607 throw NoMatchingElement ();
1611 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1614 foreach (var element in source) {
1615 initValue = selector (element, initValue);
1620 throw NoMatchingElement ();
1625 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1627 Check.SourceAndSelector (source, selector);
1631 foreach (var element in source) {
1632 int? item = selector (element);
1636 else if (item > max)
1646 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1648 Check.SourceAndSelector (source, selector);
1652 foreach (var element in source) {
1653 long? item = selector (element);
1657 else if (item > max)
1667 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1669 Check.SourceAndSelector (source, selector);
1673 foreach (var element in source) {
1674 double? item = selector (element);
1678 else if (item > max)
1688 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1690 Check.SourceAndSelector (source, selector);
1694 foreach (var element in source) {
1695 float? item = selector (element);
1699 else if (item > max)
1709 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1711 Check.SourceAndSelector (source, selector);
1714 decimal? max = null;
1715 foreach (var element in source) {
1716 decimal? item = selector (element);
1720 else if (item > max)
1730 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1732 Check.SourceAndSelector (source, selector);
1735 return source.Select (selector).Max ();
1742 public static int Min (this IEnumerable<int> source)
1744 Check.Source (source);
1747 var min = int.MaxValue;
1748 foreach (var element in source){
1749 min = Math.Min (element, min);
1753 throw EmptySequence ();
1757 public static long Min (this IEnumerable<long> source)
1759 Check.Source (source);
1762 var min = long.MaxValue;
1763 foreach (var element in source){
1764 min = Math.Min (element, min);
1768 throw EmptySequence ();
1772 public static double Min (this IEnumerable<double> source)
1774 Check.Source (source);
1777 var min = double.MaxValue;
1778 foreach (var element in source){
1779 min = Math.Min (element, min);
1783 throw EmptySequence ();
1787 public static float Min (this IEnumerable<float> source)
1789 Check.Source (source);
1792 var min = float.MaxValue;
1793 foreach (var element in source){
1794 min = Math.Min (element, min);
1798 throw EmptySequence ();
1802 public static decimal Min (this IEnumerable<decimal> source)
1804 Check.Source (source);
1807 var min = decimal.MaxValue;
1808 foreach (var element in source){
1809 min = Math.Min (element, min);
1813 throw EmptySequence ();
1817 public static int? Min (this IEnumerable<int?> source)
1819 Check.Source (source);
1822 var min = int.MaxValue;
1824 foreach (var element in source) {
1825 if (!element.HasValue)
1828 min = Math.Min (element.Value, min);
1838 public static long? Min (this IEnumerable<long?> source)
1840 Check.Source (source);
1843 var min = long.MaxValue;
1845 foreach (var element in source) {
1846 if (!element.HasValue)
1849 min = Math.Min (element.Value, min);
1859 public static double? Min (this IEnumerable<double?> source)
1861 Check.Source (source);
1864 var min = double.MaxValue;
1866 foreach (var element in source) {
1867 if (!element.HasValue)
1870 min = Math.Min (element.Value, min);
1880 public static float? Min (this IEnumerable<float?> source)
1882 Check.Source (source);
1885 var min = float.MaxValue;
1887 foreach (var element in source) {
1888 if (!element.HasValue)
1891 min = Math.Min (element.Value, min);
1901 public static decimal? Min (this IEnumerable<decimal?> source)
1903 Check.Source (source);
1906 var min = decimal.MaxValue;
1908 foreach (var element in source) {
1909 if (!element.HasValue)
1912 min = Math.Min (element.Value, min);
1922 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1924 Check.Source (source);
1926 var comparer = Comparer<TSource>.Default;
1928 TSource min = default (TSource);
1930 if (default (TSource) == null){
1931 foreach (var element in source) {
1932 if (element == null)
1935 if (min == null || comparer.Compare (element, min) < 0)
1940 foreach (var element in source) {
1946 if (comparer.Compare (element, min) < 0)
1950 throw EmptySequence ();
1955 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1957 Check.SourceAndSelector (source, selector);
1960 var min = int.MaxValue;
1961 foreach (var element in source){
1962 min = Math.Min (selector (element), min);
1966 throw NoMatchingElement ();
1970 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1972 Check.SourceAndSelector (source, selector);
1975 var min = long.MaxValue;
1976 foreach (var element in source){
1977 min = Math.Min (selector (element), min);
1981 throw NoMatchingElement ();
1985 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1987 Check.SourceAndSelector (source, selector);
1990 var min = double.MaxValue;
1991 foreach (var element in source){
1992 min = Math.Min (selector (element), min);
1996 throw NoMatchingElement ();
2000 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2002 Check.SourceAndSelector (source, selector);
2005 var min = float.MaxValue;
2006 foreach (var element in source){
2007 min = Math.Min (selector (element), min);
2011 throw NoMatchingElement ();
2015 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2017 Check.SourceAndSelector (source, selector);
2020 var min = decimal.MaxValue;
2021 foreach (var element in source){
2022 min = Math.Min (selector (element), min);
2026 throw NoMatchingElement ();
2030 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2032 Check.SourceAndSelector (source, selector);
2036 foreach (var element in source) {
2037 int? item = selector (element);
2041 else if (item < min)
2051 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2053 Check.SourceAndSelector (source, selector);
2057 foreach (var element in source) {
2058 long? item = selector (element);
2062 else if (item < min)
2072 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2074 Check.SourceAndSelector (source, selector);
2078 foreach (var element in source) {
2079 float? item = selector (element);
2083 else if (item < min)
2093 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2095 Check.SourceAndSelector (source, selector);
2099 foreach (var element in source) {
2100 double? item = selector (element);
2104 else if (item < min)
2114 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2116 Check.SourceAndSelector (source, selector);
2119 decimal? min = null;
2120 foreach (var element in source) {
2121 decimal? item = selector (element);
2125 else if (item < min)
2135 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2137 Check.SourceAndSelector (source, selector);
2140 return source.Select (selector).Min ();
2147 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
2149 Check.Source (source);
2151 return CreateOfTypeIterator<TResult> (source);
2154 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
2156 foreach (object element in source)
2157 if (element is TResult)
2158 yield return (TResult) element;
2165 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2166 Func<TSource, TKey> keySelector)
2168 return OrderBy<TSource, TKey> (source, keySelector, null);
2171 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
2172 Func<TSource, TKey> keySelector,
2173 IComparer<TKey> comparer)
2175 Check.SourceAndKeySelector (source, keySelector);
2177 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
2182 #region OrderByDescending
2184 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2185 Func<TSource, TKey> keySelector)
2187 return OrderByDescending<TSource, TKey> (source, keySelector, null);
2190 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
2191 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2193 Check.SourceAndKeySelector (source, keySelector);
2195 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
2202 public static IEnumerable<int> Range (int start, int count)
2205 throw new ArgumentOutOfRangeException ("count");
2207 if (((long) start + count) - 1L > int.MaxValue)
2208 throw new ArgumentOutOfRangeException ();
2210 return CreateRangeIterator (start, count);
2213 static IEnumerable<int> CreateRangeIterator (int start, int count)
2215 for (int i = 0; i < count; i++)
2216 yield return start + i;
2223 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
2226 throw new ArgumentOutOfRangeException ();
2228 return CreateRepeatIterator (element, count);
2231 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
2233 for (int i = 0; i < count; i++)
2234 yield return element;
2241 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
2243 Check.Source (source);
2245 return CreateReverseIterator (source);
2248 static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
2250 var array = source.ToArray ();
2252 for (int i = array.Length - 1; i >= 0; i--)
2253 yield return array [i];
2260 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
2262 Check.SourceAndSelector (source, selector);
2264 return CreateSelectIterator (source, selector);
2267 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
2269 foreach (var element in source)
2270 yield return selector (element);
2273 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2275 Check.SourceAndSelector (source, selector);
2277 return CreateSelectIterator (source, selector);
2280 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
2283 foreach (TSource element in source) {
2284 yield return selector (element, counter);
2293 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2295 Check.SourceAndSelector (source, selector);
2297 return CreateSelectManyIterator (source, selector);
2300 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
2302 foreach (TSource element in source)
2303 foreach (TResult item in selector (element))
2307 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2309 Check.SourceAndSelector (source, selector);
2311 return CreateSelectManyIterator (source, selector);
2314 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
2317 foreach (TSource element in source) {
2318 foreach (TResult item in selector (element, counter))
2324 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2325 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2327 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2329 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2332 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2333 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2335 foreach (TSource element in source)
2336 foreach (TCollection collection in collectionSelector (element))
2337 yield return selector (element, collection);
2340 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2341 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
2343 Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
2345 return CreateSelectManyIterator (source, collectionSelector, resultSelector);
2348 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
2349 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2352 foreach (TSource element in source)
2353 foreach (TCollection collection in collectionSelector (element, counter++))
2354 yield return selector (element, collection);
2361 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
2364 var item = default (TSource);
2366 foreach (var element in source) {
2367 if (!predicate (element))
2371 throw MoreThanOneMatchingElement ();
2377 if (!found && fallback == Fallback.Throw)
2378 throw NoMatchingElement ();
2383 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2385 Check.Source (source);
2387 #if !FULL_AOT_RUNTIME
2388 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
2391 var item = default (TSource);
2393 foreach (var element in source) {
2395 throw MoreThanOneElement ();
2402 throw NoMatchingElement ();
2408 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2410 Check.SourceAndPredicate (source, predicate);
2412 return source.Single (predicate, Fallback.Throw);
2417 #region SingleOrDefault
2419 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2421 Check.Source (source);
2423 #if !FULL_AOT_RUNTIME
2424 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
2427 var item = default (TSource);
2429 foreach (var element in source) {
2431 throw MoreThanOneMatchingElement ();
2441 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2443 Check.SourceAndPredicate (source, predicate);
2445 return source.Single (predicate, Fallback.Default);
2452 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2454 Check.Source (source);
2456 return CreateSkipIterator (source, count);
2459 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
2461 var enumerator = source.GetEnumerator ();
2464 if (!enumerator.MoveNext ())
2467 while (enumerator.MoveNext ())
2468 yield return enumerator.Current;
2471 enumerator.Dispose ();
2479 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2481 Check.SourceAndPredicate (source, predicate);
2483 return CreateSkipWhileIterator (source, predicate);
2486 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2490 foreach (TSource element in source) {
2492 yield return element;
2494 if (!predicate (element)) {
2495 yield return element;
2501 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2503 Check.SourceAndPredicate (source, predicate);
2505 return CreateSkipWhileIterator (source, predicate);
2508 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2513 foreach (TSource element in source) {
2515 yield return element;
2517 if (!predicate (element, counter)) {
2518 yield return element;
2529 public static int Sum (this IEnumerable<int> source)
2531 Check.Source (source);
2534 foreach (var element in source)
2535 total = checked (total + element);
2539 public static int? Sum (this IEnumerable<int?> source)
2541 Check.Source (source);
2544 foreach (var element in source) {
2545 if (element.HasValue)
2546 total = checked (total + element.Value);
2551 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2553 Check.SourceAndSelector (source, selector);
2556 foreach (var element in source)
2557 total = checked (total + selector (element));
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 var value = selector (element);
2570 total = checked (total + value.Value);
2575 public static long Sum (this IEnumerable<long> source)
2577 Check.Source (source);
2581 foreach (var element in source)
2582 total = checked (total + element);
2586 public static long? Sum (this IEnumerable<long?> source)
2588 Check.Source (source);
2591 foreach (var element in source) {
2592 if (element.HasValue)
2593 total = checked (total + element.Value);
2598 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2600 Check.SourceAndSelector (source, selector);
2603 foreach (var element in source)
2604 total = checked (total + selector (element));
2608 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2610 Check.SourceAndSelector (source, selector);
2613 foreach (var element in source) {
2614 var value = selector (element);
2616 total = checked (total + value.Value);
2621 public static double Sum (this IEnumerable<double> source)
2623 Check.Source (source);
2627 foreach (var element in source)
2628 total = checked (total + element);
2632 public static double? Sum (this IEnumerable<double?> source)
2634 Check.Source (source);
2637 foreach (var element in source) {
2638 if (element.HasValue)
2639 total = checked (total + element.Value);
2644 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2646 Check.SourceAndSelector (source, selector);
2650 foreach (var element in source)
2651 total = checked (total + selector (element));
2655 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2657 Check.SourceAndSelector (source, selector);
2660 foreach (var element in source) {
2661 var value = selector (element);
2663 total = checked (total + value.Value);
2668 public static float Sum (this IEnumerable<float> source)
2670 Check.Source (source);
2674 foreach (var element in source)
2675 total = checked (total + element);
2679 public static float? Sum (this IEnumerable<float?> source)
2681 Check.Source (source);
2684 foreach (var element in source) {
2685 if (element.HasValue)
2686 total = checked (total + element.Value);
2692 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
2694 Check.SourceAndSelector (source, selector);
2696 foreach (var element in source)
2697 total = checked (total + selector (element));
2701 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
2703 Check.SourceAndSelector (source, selector);
2706 foreach (var element in source) {
2707 var value = selector (element);
2709 total = checked (total + value.Value);
2714 public static decimal Sum (this IEnumerable<decimal> source)
2716 Check.Source (source);
2719 foreach (var element in source)
2720 total = checked (total + element);
2724 public static decimal? Sum (this IEnumerable<decimal?> source)
2726 Check.Source (source);
2729 foreach (var element in source) {
2730 if (element.HasValue)
2731 total = checked (total + element.Value);
2737 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2739 Check.SourceAndSelector (source, selector);
2742 foreach (var element in source)
2743 total = checked (total + selector (element));
2747 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2749 Check.SourceAndSelector (source, selector);
2752 foreach (var element in source) {
2753 var value = selector (element);
2755 total = checked (total + value.Value);
2764 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2766 Check.Source (source);
2769 return EmptyOf<TSource>.Instance;
2771 return CreateTakeIterator (source, count);
2774 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2777 foreach (TSource element in source) {
2778 yield return element;
2780 if (++counter == count)
2789 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2791 Check.SourceAndPredicate (source, predicate);
2793 return CreateTakeWhileIterator (source, predicate);
2796 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2798 foreach (var element in source) {
2799 if (!predicate (element))
2802 yield return element;
2806 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2808 Check.SourceAndPredicate (source, predicate);
2810 return CreateTakeWhileIterator (source, predicate);
2813 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2816 foreach (var element in source) {
2817 if (!predicate (element, counter))
2820 yield return element;
2829 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2831 return ThenBy<TSource, TKey> (source, keySelector, null);
2834 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2835 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2837 Check.SourceAndKeySelector (source, keySelector);
2839 #if FULL_AOT_RUNTIME
2840 var oe = source as OrderedEnumerable <TSource>;
2842 return oe.CreateOrderedEnumerable (keySelector, comparer, false);
2845 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2850 #region ThenByDescending
2852 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2853 Func<TSource, TKey> keySelector)
2855 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2858 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2859 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2861 Check.SourceAndKeySelector (source, keySelector);
2863 #if FULL_AOT_RUNTIME
2864 var oe = source as OrderedEnumerable <TSource>;
2866 return oe.CreateOrderedEnumerable (keySelector, comparer, true);
2868 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2875 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2877 Check.Source (source);
2880 var collection = source as ICollection<TSource>;
2881 if (collection != null) {
2882 if (collection.Count == 0)
2883 return EmptyOf<TSource>.Instance;
2885 array = new TSource [collection.Count];
2886 collection.CopyTo (array, 0);
2891 array = EmptyOf<TSource>.Instance;
2892 foreach (var element in source) {
2893 if (pos == array.Length) {
2895 array = new TSource [4];
2897 Array.Resize (ref array, pos * 2);
2900 array[pos++] = element;
2903 if (pos != array.Length)
2904 Array.Resize (ref array, pos);
2911 #region ToDictionary
2912 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2913 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2915 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2918 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2919 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2921 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2923 if (comparer == null)
2924 comparer = EqualityComparer<TKey>.Default;
2926 var dict = new Dictionary<TKey, TElement> (comparer);
2927 foreach (var e in source)
2928 dict.Add (keySelector (e), elementSelector (e));
2933 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2934 Func<TSource, TKey> keySelector)
2936 return ToDictionary (source, keySelector, null);
2939 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2940 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2942 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2948 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2950 Check.Source (source);
2952 return new List<TSource> (source);
2958 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2960 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2963 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2964 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2966 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2969 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2970 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2972 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2975 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2976 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2978 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2980 List<TElement> nullKeyElements = null;
2982 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2983 foreach (var element in source) {
2984 var key = keySelector (element);
2986 List<TElement> list;
2989 if (nullKeyElements == null)
2990 nullKeyElements = new List<TElement> ();
2992 list = nullKeyElements;
2993 } else if (!dictionary.TryGetValue (key, out list)) {
2994 list = new List<TElement> ();
2995 dictionary.Add (key, list);
2998 list.Add (elementSelector (element));
3001 return new Lookup<TKey, TElement> (dictionary, nullKeyElements);
3006 #region SequenceEqual
3008 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3010 return first.SequenceEqual (second, null);
3013 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3015 Check.FirstAndSecond (first, second);
3017 if (comparer == null)
3018 comparer = EqualityComparer<TSource>.Default;
3020 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
3021 second_enumerator = second.GetEnumerator ()) {
3023 while (first_enumerator.MoveNext ()) {
3024 if (!second_enumerator.MoveNext ())
3027 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
3031 return !second_enumerator.MoveNext ();
3039 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
3041 Check.FirstAndSecond (first, second);
3043 return first.Union (second, null);
3046 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3048 Check.FirstAndSecond (first, second);
3050 if (comparer == null)
3051 comparer = EqualityComparer<TSource>.Default;
3053 return CreateUnionIterator (first, second, comparer);
3056 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
3058 var items = new HashSet<TSource> (comparer);
3059 foreach (var element in first) {
3060 if (! items.Contains (element)) {
3061 items.Add (element);
3062 yield return element;
3066 foreach (var element in second) {
3067 if (! items.Contains (element)) {
3068 items.Add (element);
3069 yield return element;
3079 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
3081 Check.FirstAndSecond (first, second);
3082 if (resultSelector == null)
3083 throw new ArgumentNullException ("resultSelector");
3085 return CreateZipIterator (first, second, resultSelector);
3088 static IEnumerable<TResult> CreateZipIterator<TFirst, TSecond, TResult> (IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
3090 using (IEnumerator<TFirst> first_enumerator = first.GetEnumerator ()) {
3091 using (IEnumerator<TSecond> second_enumerator = second.GetEnumerator ()) {
3093 while (first_enumerator.MoveNext () && second_enumerator.MoveNext ()) {
3094 yield return selector (first_enumerator.Current, second_enumerator.Current);
3105 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
3107 Check.SourceAndPredicate (source, predicate);
3109 // It cannot be IList<TSource> because it may break on user implementation
3110 var array = source as TSource[];
3112 return CreateWhereIterator (array, predicate);
3114 return CreateWhereIterator (source, predicate);
3117 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
3119 foreach (TSource element in source)
3120 if (predicate (element))
3121 yield return element;
3124 static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, bool> predicate)
3126 for (int i = 0; i < source.Length; ++i) {
3127 var element = source [i];
3128 if (predicate (element))
3129 yield return element;
3133 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3135 Check.SourceAndPredicate (source, predicate);
3137 var array = source as TSource[];
3139 return CreateWhereIterator (array, predicate);
3141 return CreateWhereIterator (source, predicate);
3144 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
3147 foreach (TSource element in source) {
3148 if (predicate (element, counter))
3149 yield return element;
3154 static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, int, bool> predicate)
3156 for (int i = 0; i < source.Length; ++i) {
3157 var element = source [i];
3158 if (predicate (element, i))
3159 yield return element;
3165 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
3168 return ReadOnlyCollectionOf<TSource>.Empty;
3170 var ro = source as ReadOnlyCollection<TSource>;
3174 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());
3177 #region Exception helpers
3179 static Exception EmptySequence ()
3181 return new InvalidOperationException (Locale.GetText ("Sequence contains no elements"));
3183 static Exception NoMatchingElement ()
3185 return new InvalidOperationException (Locale.GetText ("Sequence contains no matching element"));
3187 static Exception MoreThanOneElement ()
3189 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one element"));
3191 static Exception MoreThanOneMatchingElement ()
3193 return new InvalidOperationException (Locale.GetText ("Sequence contains more than one matching element"));