1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // Marek Safar (marek.safar@gmail.com)
21 // Antonello Provenzano <antonello@deveel.com>
22 // Alejandro Serrano "Serras" (trupill@yahoo.es)
26 using System.Collections;
27 using System.Collections.Generic;
28 using System.Collections.ObjectModel;
32 public static class Enumerable
35 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
38 throw new ArgumentNullException ("source");
40 throw new ArgumentNullException ("func");
42 // custom foreach so that we can efficiently throw an exception
43 // if zero elements and treat the first element differently
44 using (IEnumerator<TSource> enumerator = source.GetEnumerator ()) {
45 if (!enumerator.MoveNext ())
46 throw new InvalidOperationException ("No elements in source list");
48 TSource folded = enumerator.Current;
49 while (enumerator.MoveNext ())
50 folded = func (folded, enumerator.Current);
56 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
57 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
59 if (source == null || func == null)
60 throw new ArgumentNullException ();
62 TAccumulate folded = seed;
63 foreach (TSource element in source)
64 folded = func (folded, element);
69 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
72 throw new ArgumentNullException ("source");
74 throw new ArgumentNullException ("func");
75 if (resultSelector == null)
76 throw new ArgumentNullException ("resultSelector");
78 TAccumulate result = seed;
79 foreach (TSource e in source)
80 result = func (result, e);
81 return resultSelector (result);
86 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
88 if (source == null || predicate == null)
89 throw new ArgumentNullException ();
91 foreach (TSource element in source)
92 if (!predicate (element))
99 public static bool Any<TSource> (this IEnumerable<TSource> source)
102 throw new ArgumentNullException ();
104 foreach (TSource element in source)
110 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
112 if (source == null || predicate == null)
113 throw new ArgumentNullException ();
115 foreach (TSource element in source)
116 if (predicate (element))
123 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
130 public static double Average (this IEnumerable<int> source)
133 throw new ArgumentNullException ();
137 foreach (int element in source) {
143 throw new InvalidOperationException ();
145 return (double) sum / (double) counter;
149 public static double? Average (this IEnumerable<int?> source)
152 throw new ArgumentNullException ();
154 bool onlyNull = true;
157 foreach (int? element in source) {
158 if (element.HasValue) {
160 sum += element.Value;
164 return (onlyNull ? null : (double?) sum / (double?) counter);
168 public static double Average (this IEnumerable<long> source)
171 throw new ArgumentNullException ();
175 foreach (long element in source) {
181 throw new InvalidOperationException ();
183 return (double) sum / (double) counter;
187 public static double? Average (this IEnumerable<long?> source)
190 throw new ArgumentNullException ();
192 bool onlyNull = true;
195 foreach (long? element in source) {
196 if (element.HasValue) {
198 sum += element.Value;
202 return (onlyNull ? null : (double?) sum / (double?) counter);
206 public static double Average (this IEnumerable<double> source)
209 throw new ArgumentNullException ();
213 foreach (double element in source) {
219 throw new InvalidOperationException ();
221 return sum / counter;
225 public static double? Average (this IEnumerable<double?> source)
228 throw new ArgumentNullException ();
230 bool onlyNull = true;
233 foreach (double? element in source) {
234 if (element.HasValue) {
236 sum += element.Value;
240 return (onlyNull ? null : (double?) (sum / counter));
244 public static decimal Average (this IEnumerable<decimal> source)
247 throw new ArgumentNullException ();
251 foreach (decimal element in source) {
257 throw new InvalidOperationException ();
259 return sum / counter;
263 public static decimal? Average (this IEnumerable<decimal?> source)
266 throw new ArgumentNullException ();
268 bool onlyNull = true;
271 foreach (decimal? element in source) {
272 if (element.HasValue) {
274 sum += element.Value;
278 return (onlyNull ? null : (decimal?) (sum / counter));
282 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
284 if (source == null || selector == null)
285 throw new ArgumentNullException ();
289 foreach (TSource item in source) {
290 sum += selector (item);
295 throw new InvalidOperationException ();
297 return (double) sum / (double) counter;
301 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
303 if (source == null || selector == null)
304 throw new ArgumentNullException ();
306 bool onlyNull = true;
309 foreach (TSource item in source) {
310 int? element = selector (item);
311 if (element.HasValue) {
313 sum += element.Value;
317 return (onlyNull ? null : (double?) sum / (double?) counter);
321 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
323 if (source == null || selector == null)
324 throw new ArgumentNullException ();
328 foreach (TSource item in source) {
329 sum += selector (item);
334 throw new InvalidOperationException ();
336 return (double) sum / (double) counter;
340 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
342 if (source == null || selector == null)
343 throw new ArgumentNullException ();
345 bool onlyNull = true;
348 foreach (TSource item in source) {
349 long? element = selector (item);
350 if (element.HasValue) {
352 sum += element.Value;
356 return (onlyNull ? null : (double?) sum / (double?) counter);
360 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
362 if (source == null || selector == null)
363 throw new ArgumentNullException ();
367 foreach (TSource item in source) {
368 sum += selector (item);
373 throw new InvalidOperationException ();
375 return sum / counter;
379 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
381 if (source == null || selector == null)
382 throw new ArgumentNullException ();
384 bool onlyNull = true;
387 foreach (TSource item in source) {
388 double? element = selector (item);
389 if (element.HasValue) {
391 sum += element.Value;
395 return (onlyNull ? null : (double?) (sum / counter));
399 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
401 if (source == null || selector == null)
402 throw new ArgumentNullException ();
406 foreach (TSource item in source) {
407 sum += selector (item);
412 throw new InvalidOperationException ();
414 return sum / counter;
418 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
420 if (source == null || selector == null)
421 throw new ArgumentNullException ();
423 bool onlyNull = true;
426 foreach (TSource item in source) {
427 decimal? element = selector (item);
428 if (element.HasValue) {
430 sum += element.Value;
434 return (onlyNull ? null : (decimal?) (sum / counter));
439 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
442 throw new ArgumentNullException ();
444 foreach (object element in source)
445 yield return (TResult) element;
450 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
452 if (first == null || second == null)
453 throw new ArgumentNullException ();
455 foreach (TSource element in first)
456 yield return element;
457 foreach (TSource element in second)
458 yield return element;
465 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
467 if (source is ICollection<TSource>) {
468 ICollection<TSource> collection = (ICollection<TSource>) source;
469 return collection.Contains (value);
472 return Contains<TSource> (source, value, null);
476 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
479 throw new ArgumentNullException ("source");
481 if (comparer == null)
482 comparer = EqualityComparer<TSource>.Default;
485 foreach (TSource e in source) {
486 if (comparer.Equals (e, value))
495 public static int Count<TSource> (this IEnumerable<TSource> source)
498 throw new ArgumentNullException ();
500 if (source is ICollection<TSource>)
501 return ((ICollection<TSource>) source).Count;
504 foreach (TSource element in source)
511 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
513 if (source == null || selector == null)
514 throw new ArgumentNullException ();
517 foreach (TSource element in source)
518 if (selector (element))
525 #region DefaultIfEmpty
527 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
530 throw new ArgumentNullException ();
533 foreach (TSource item in source) {
539 yield return default (TSource);
543 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
546 throw new ArgumentNullException ();
549 foreach (TSource item in source) {
555 yield return defaultValue;
562 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
564 return Distinct<TSource> (source, null);
567 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
570 throw new ArgumentNullException ();
572 if (comparer == null)
573 comparer = EqualityComparer<TSource>.Default;
575 List<TSource> items = new List<TSource> ();
576 foreach (TSource element in source) {
577 if (!Contains (items, element, comparer)) {
579 yield return element;
587 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
590 throw new ArgumentNullException ();
592 throw new ArgumentOutOfRangeException ();
594 if (source is IList<TSource>)
595 return ((IList<TSource>) source) [index];
598 foreach (TSource element in source) {
599 if (counter == index)
603 throw new ArgumentOutOfRangeException ();
609 #region ElementAtOrDefault
611 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
614 throw new ArgumentNullException ();
616 return default (TSource);
618 if (source is IList<TSource>) {
619 if (((IList<TSource>) source).Count >= index)
620 return default (TSource);
622 return ((IList<TSource>) source) [index];
625 foreach (TSource element in source) {
626 if (counter == index)
630 return default (TSource);
637 public static IEnumerable<TResult> Empty<TResult> ()
639 return new List<TResult> ();
645 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
647 return Except (first, second, null);
650 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
652 if (first == null || second == null)
653 throw new ArgumentNullException ();
655 if (comparer == null)
656 comparer = EqualityComparer<TSource>.Default;
658 List<TSource> items = new List<TSource> (Distinct (first));
659 foreach (TSource element in second) {
660 int index = IndexOf (items, element, comparer);
664 items.RemoveAt (index);
666 foreach (TSource item in items)
674 public static TSource First<TSource> (this IEnumerable<TSource> source)
677 throw new ArgumentNullException ();
679 foreach (TSource element in source)
682 throw new InvalidOperationException ();
686 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
688 if (source == null || predicate == null)
689 throw new ArgumentNullException ();
691 foreach (TSource element in source) {
692 if (predicate (element))
696 throw new InvalidOperationException ();
701 #region FirstOrDefault
703 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
706 throw new ArgumentNullException ();
708 foreach (TSource element in source)
711 return default (TSource);
715 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
717 if (source == null || predicate == null)
718 throw new ArgumentNullException ();
720 foreach (TSource element in source) {
721 if (predicate (element))
725 return default (TSource);
732 private static List<T> ContainsGroup<K, T> (
733 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
735 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
736 foreach (KeyValuePair<K, List<T>> value in items) {
737 if (comparerInUse.Equals (value.Key, key))
744 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
745 Func<TSource, TKey> keySelector)
747 return GroupBy<TSource, TKey> (source, keySelector, null);
751 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
752 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
754 if (source == null || keySelector == null)
755 throw new ArgumentNullException ();
757 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
758 List<TSource> nullList = new List<TSource> ();
760 int nullCounter = -1;
762 foreach (TSource element in source) {
763 TKey key = keySelector (element);
765 nullList.Add (element);
766 if (nullCounter == -1) {
767 nullCounter = counter;
771 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
773 group = new List<TSource> ();
774 groups.Add (key, group);
782 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
783 if (counter == nullCounter) {
784 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
785 yield return nullGroup;
788 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
789 yield return grouping;
795 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
796 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
798 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
802 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
803 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
805 if (source == null || keySelector == null || elementSelector == null)
806 throw new ArgumentNullException ();
808 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
809 List<TElement> nullList = new List<TElement> ();
811 int nullCounter = -1;
813 foreach (TSource item in source) {
814 TKey key = keySelector (item);
815 TElement element = elementSelector (item);
817 nullList.Add (element);
818 if (nullCounter == -1) {
819 nullCounter = counter;
823 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
825 group = new List<TElement> ();
826 groups.Add (key, group);
834 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
835 if (counter == nullCounter) {
836 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
837 yield return nullGroup;
840 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
841 yield return grouping;
850 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
851 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
852 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
854 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
857 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
858 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
859 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
860 IEqualityComparer<TKey> comparer)
862 if (outer == null || inner == null || outerKeySelector == null ||
863 innerKeySelector == null || resultSelector == null)
864 throw new ArgumentNullException ();
866 if (comparer == null)
867 comparer = EqualityComparer<TKey>.Default;
869 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
870 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
871 foreach (U element in inner)
873 K innerKey = innerKeySelector (element);
874 if (!innerKeys.ContainsKey (innerKey))
875 innerKeys.Add (innerKey, new List<U> ());
876 innerKeys[innerKey].Add (element);
879 foreach (TOuter element in outer) {
880 TKey outerKey = outerKeySelector (element);
881 if (innerKeys.Contains (outerKey))
882 yield return resultSelector (element, innerKeys [outerKey]);
891 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
893 if (first == null || second == null)
894 throw new ArgumentNullException ();
896 List<TSource> items = new List<TSource> (Distinct (first));
897 bool [] marked = new bool [items.Count];
898 for (int i = 0; i < marked.Length; i++)
901 foreach (TSource element in second) {
902 int index = IndexOf (items, element);
904 marked [index] = true;
906 for (int i = 0; i < marked.Length; i++) {
908 yield return items [i];
916 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
917 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
918 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
920 if (outer == null || inner == null || outerKeySelector == null ||
921 innerKeySelector == null || resultSelector == null)
922 throw new ArgumentNullException ();
924 if (comparer == null)
925 comparer = EqualityComparer<TKey>.Default;
927 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
928 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
929 foreach (U element in inner)
931 K innerKey = innerKeySelector (element);
932 if (!innerKeys.ContainsKey (innerKey))
933 innerKeys.Add (innerKey, new List<U> ());
934 innerKeys[innerKey].Add (element);
937 foreach (TOuter element in outer) {
938 TKey outerKey = outerKeySelector (element);
939 if (innerKeys.Contains (outerKey)) {
940 foreach (TInner innerElement in innerKeys [outerKey])
941 yield return resultSelector (element, innerElement);
946 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
947 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
948 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
950 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
956 public static TSource Last<TSource> (this IEnumerable<TSource> source)
959 throw new ArgumentNullException ();
961 bool noElements = true;
962 TSource lastElement = default (TSource);
963 foreach (TSource element in source) {
964 if (noElements) noElements = false;
965 lastElement = element;
971 throw new InvalidOperationException ();
974 public static TSource Last<TSource> (this IEnumerable<TSource> source,
975 Func<TSource, bool> predicate)
977 if (source == null || predicate == null)
978 throw new ArgumentNullException ();
980 bool noElements = true;
981 TSource lastElement = default (TSource);
982 foreach (TSource element in source) {
983 if (predicate (element)) {
984 if (noElements) noElements = false;
985 lastElement = element;
992 throw new InvalidOperationException ();
997 #region LastOrDefault
999 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
1002 throw new ArgumentNullException ();
1004 TSource lastElement = default (TSource);
1005 foreach (TSource element in source)
1006 lastElement = element;
1011 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source,
1012 Func<TSource, bool> predicate)
1014 if (source == null || predicate == null)
1015 throw new ArgumentNullException ();
1017 TSource lastElement = default (TSource);
1018 foreach (TSource element in source) {
1019 if (predicate (element))
1020 lastElement = element;
1029 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1032 throw new ArgumentNullException ();
1035 foreach (TSource element in source)
1041 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1043 if (source == null || selector == null)
1044 throw new ArgumentNullException ();
1047 foreach (TSource element in source)
1048 if (selector (element))
1058 public static int Max (this IEnumerable<int> source)
1061 throw new ArgumentNullException ();
1063 int maximum = int.MinValue;
1065 foreach (int element in source) {
1066 if (element > maximum)
1072 throw new InvalidOperationException ();
1078 public static int? Max (this IEnumerable<int?> source)
1081 throw new ArgumentNullException ();
1083 bool onlyNull = true;
1084 int? maximum = int.MinValue;
1085 foreach (int? element in source) {
1086 if (element.HasValue) {
1088 if (element > maximum)
1092 return (onlyNull ? null : maximum);
1096 public static long Max (this IEnumerable<long> source)
1099 throw new ArgumentNullException ();
1101 long maximum = long.MinValue;
1103 foreach (long element in source) {
1104 if (element > maximum)
1110 throw new InvalidOperationException ();
1116 public static long? Max (this IEnumerable<long?> source)
1119 throw new ArgumentNullException ();
1121 bool onlyNull = true;
1122 long? maximum = long.MinValue;
1123 foreach (long? element in source) {
1124 if (element.HasValue) {
1126 if (element > maximum)
1130 return (onlyNull ? null : maximum);
1134 public static double Max (this IEnumerable<double> source)
1137 throw new ArgumentNullException ();
1139 double maximum = double.MinValue;
1141 foreach (double element in source) {
1142 if (element > maximum)
1148 throw new InvalidOperationException ();
1154 public static double? Max (this IEnumerable<double?> source)
1157 throw new ArgumentNullException ();
1159 bool onlyNull = true;
1160 double? maximum = double.MinValue;
1161 foreach (double? element in source) {
1162 if (element.HasValue) {
1164 if (element > maximum)
1168 return (onlyNull ? null : maximum);
1172 public static decimal Max (this IEnumerable<decimal> source)
1175 throw new ArgumentNullException ();
1177 decimal maximum = decimal.MinValue;
1179 foreach (decimal element in source) {
1180 if (element > maximum)
1186 throw new InvalidOperationException ();
1192 public static decimal? Max (this IEnumerable<decimal?> source)
1195 throw new ArgumentNullException ();
1197 bool onlyNull = true;
1198 decimal? maximum = decimal.MinValue;
1199 foreach (decimal? element in source) {
1200 if (element.HasValue) {
1202 if (element > maximum)
1206 return (onlyNull ? null : maximum);
1210 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1213 throw new ArgumentNullException ();
1215 bool notAssigned = true;
1216 TSource maximum = default (TSource);
1218 foreach (TSource element in source) {
1221 notAssigned = false;
1224 if (element is IComparable<TSource>)
1225 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1226 else if (element is System.IComparable)
1227 comparison = ((System.IComparable) element).CompareTo (maximum);
1229 throw new ArgumentNullException ();
1238 throw new InvalidOperationException ();
1244 public static int Max<TSource> (this IEnumerable<TSource> source,
1245 Func<TSource, int> selector)
1247 if (source == null || selector == null)
1248 throw new ArgumentNullException ();
1250 int maximum = int.MinValue;
1252 foreach (TSource item in source) {
1253 int element = selector (item);
1254 if (element > maximum)
1260 throw new InvalidOperationException ();
1266 public static int? Max<TSource> (this IEnumerable<TSource> source,
1267 Func<TSource, int?> selector)
1269 if (source == null || selector == null)
1270 throw new ArgumentNullException ();
1272 bool onlyNull = true;
1273 int? maximum = int.MinValue;
1274 foreach (TSource item in source) {
1275 int? element = selector (item);
1276 if (element.HasValue) {
1278 if (element > maximum)
1282 return (onlyNull ? null : maximum);
1286 public static long Max<TSource> (this IEnumerable<TSource> source,
1287 Func<TSource, long> selector)
1289 if (source == null || selector == null)
1290 throw new ArgumentNullException ();
1292 long maximum = long.MinValue;
1294 foreach (TSource item in source) {
1295 long element = selector (item);
1296 if (element > maximum)
1302 throw new InvalidOperationException ();
1308 public static long? Max<TSource> (this IEnumerable<TSource> source,
1309 Func<TSource, long?> selector)
1311 if (source == null || selector == null)
1312 throw new ArgumentNullException ();
1314 bool onlyNull = true;
1315 long? maximum = long.MinValue;
1316 foreach (TSource item in source) {
1317 long? element = selector (item);
1318 if (element.HasValue) {
1320 if (element > maximum)
1324 return (onlyNull ? null : maximum);
1328 public static double Max<TSource> (this IEnumerable<TSource> source,
1329 Func<TSource, double> selector)
1331 if (source == null || selector == null)
1332 throw new ArgumentNullException ();
1334 double maximum = double.MinValue;
1336 foreach (TSource item in source) {
1337 double element = selector (item);
1338 if (element > maximum)
1344 throw new InvalidOperationException ();
1350 public static double? Max<TSource> (this IEnumerable<TSource> source,
1351 Func<TSource, double?> selector)
1353 if (source == null || selector == null)
1354 throw new ArgumentNullException ();
1356 bool onlyNull = true;
1357 double? maximum = double.MinValue;
1358 foreach (TSource item in source) {
1359 double? element = selector (item);
1360 if (element.HasValue) {
1362 if (element > maximum)
1366 return (onlyNull ? null : maximum);
1370 public static decimal Max<TSource> (this IEnumerable<TSource> source,
1371 Func<TSource, decimal> selector)
1373 if (source == null || selector == null)
1374 throw new ArgumentNullException ();
1376 decimal maximum = decimal.MinValue;
1378 foreach (TSource item in source) {
1379 decimal element = selector (item);
1380 if (element > maximum)
1386 throw new InvalidOperationException ();
1392 public static decimal? Max<TSource> (this IEnumerable<TSource> source,
1393 Func<TSource, decimal?> selector)
1395 if (source == null || selector == null)
1396 throw new ArgumentNullException ();
1398 bool onlyNull = true;
1399 decimal? maximum = decimal.MinValue;
1400 foreach (TSource item in source) {
1401 decimal? element = selector (item);
1402 if (element.HasValue) {
1404 if (element > maximum)
1408 return (onlyNull ? null : maximum);
1412 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source,
1413 Func<TSource, TResult> selector)
1415 if (source == null || selector == null)
1416 throw new ArgumentNullException ();
1418 bool notAssigned = true;
1419 TResult maximum = default (TResult);
1421 foreach (TSource item in source) {
1422 TResult element = selector (item);
1425 notAssigned = false;
1428 if (element is IComparable<TResult>)
1429 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1430 else if (element is System.IComparable)
1431 comparison = ((System.IComparable) element).CompareTo (maximum);
1433 throw new ArgumentNullException ();
1442 throw new InvalidOperationException ();
1451 public static int Min (this IEnumerable<int> source)
1454 throw new ArgumentNullException ();
1456 int minimum = int.MaxValue;
1458 foreach (int element in source) {
1459 if (element < minimum)
1465 throw new InvalidOperationException ();
1471 public static int? Min (this IEnumerable<int?> source)
1474 throw new ArgumentNullException ();
1476 bool onlyNull = true;
1477 int? minimum = int.MaxValue;
1478 foreach (int? element in source) {
1479 if (element.HasValue) {
1481 if (element < minimum)
1485 return (onlyNull ? null : minimum);
1488 public static long Min (this IEnumerable<long> source)
1491 throw new ArgumentNullException ();
1493 long minimum = long.MaxValue;
1495 foreach (long element in source) {
1496 if (element < minimum)
1502 throw new InvalidOperationException ();
1508 public static long? Min (this IEnumerable<long?> source)
1511 throw new ArgumentNullException ();
1513 bool onlyNull = true;
1514 long? minimum = long.MaxValue;
1515 foreach (long? element in source) {
1516 if (element.HasValue) {
1518 if (element < minimum)
1522 return (onlyNull ? null : minimum);
1526 public static double Min (this IEnumerable<double> source)
1529 throw new ArgumentNullException ();
1531 double minimum = double.MaxValue;
1533 foreach (double element in source) {
1534 if (element < minimum)
1540 throw new InvalidOperationException ();
1546 public static double? Min (this IEnumerable<double?> source)
1549 throw new ArgumentNullException ();
1551 bool onlyNull = true;
1552 double? minimum = double.MaxValue;
1553 foreach (double? element in source) {
1554 if (element.HasValue) {
1556 if (element < minimum)
1560 return (onlyNull ? null : minimum);
1564 public static decimal Min (this IEnumerable<decimal> source)
1567 throw new ArgumentNullException ();
1569 decimal minimum = decimal.MaxValue;
1571 foreach (decimal element in source) {
1572 if (element < minimum)
1578 throw new InvalidOperationException ();
1584 public static decimal? Min (this IEnumerable<decimal?> source)
1587 throw new ArgumentNullException ();
1589 bool onlyNull = true;
1590 decimal? minimum = decimal.MaxValue;
1591 foreach (decimal? element in source) {
1592 if (element.HasValue) {
1594 if (element < minimum)
1598 return (onlyNull ? null : minimum);
1602 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1605 throw new ArgumentNullException ();
1607 bool notAssigned = true;
1608 TSource minimum = default (TSource);
1610 foreach (TSource element in source) {
1613 notAssigned = false;
1616 if (element is IComparable<TSource>)
1617 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1618 else if (element is System.IComparable)
1619 comparison = ((System.IComparable) element).CompareTo (minimum);
1621 throw new ArgumentNullException ();
1630 throw new InvalidOperationException ();
1636 public static int Min<TSource> (this IEnumerable<TSource> source,
1637 Func<TSource, int> selector)
1639 if (source == null || selector == null)
1640 throw new ArgumentNullException ();
1642 int minimum = int.MaxValue;
1644 foreach (TSource item in source) {
1645 int element = selector (item);
1646 if (element < minimum)
1652 throw new InvalidOperationException ();
1658 public static int? Min<TSource> (this IEnumerable<TSource> source,
1659 Func<TSource, int?> selector)
1661 if (source == null || selector == null)
1662 throw new ArgumentNullException ();
1664 bool onlyNull = true;
1665 int? minimum = int.MaxValue;
1666 foreach (TSource item in source) {
1667 int? element = selector (item);
1668 if (element.HasValue) {
1670 if (element < minimum)
1674 return (onlyNull ? null : minimum);
1678 public static long Min<TSource> (this IEnumerable<TSource> source,
1679 Func<TSource, long> selector)
1681 if (source == null || selector == null)
1682 throw new ArgumentNullException ();
1684 long minimum = long.MaxValue;
1686 foreach (TSource item in source) {
1687 long element = selector (item);
1688 if (element < minimum)
1694 throw new InvalidOperationException ();
1700 public static long? Min<TSource> (this IEnumerable<TSource> source,
1701 Func<TSource, long?> selector)
1703 if (source == null || selector == null)
1704 throw new ArgumentNullException ();
1706 bool onlyNull = true;
1707 long? minimum = long.MaxValue;
1708 foreach (TSource item in source) {
1709 long? element = selector (item);
1710 if (element.HasValue) {
1712 if (element < minimum)
1716 return (onlyNull ? null : minimum);
1720 public static double Min<TSource> (this IEnumerable<TSource> source,
1721 Func<TSource, double> selector)
1723 if (source == null || selector == null)
1724 throw new ArgumentNullException ();
1726 double minimum = double.MaxValue;
1728 foreach (TSource item in source) {
1729 double element = selector (item);
1730 if (element < minimum)
1736 throw new InvalidOperationException ();
1742 public static double? Min<TSource> (this IEnumerable<TSource> source,
1743 Func<TSource, double?> selector)
1745 if (source == null || selector == null)
1746 throw new ArgumentNullException ();
1748 bool onlyNull = true;
1749 double? minimum = double.MaxValue;
1750 foreach (TSource item in source) {
1751 double? element = selector (item);
1752 if (element.HasValue) {
1754 if (element < minimum)
1758 return (onlyNull ? null : minimum);
1762 public static decimal Min<TSource> (this IEnumerable<TSource> source,
1763 Func<TSource, decimal> selector)
1765 if (source == null || selector == null)
1766 throw new ArgumentNullException ();
1768 decimal minimum = decimal.MaxValue;
1770 foreach (TSource item in source) {
1771 decimal element = selector (item);
1772 if (element < minimum)
1778 throw new InvalidOperationException ();
1784 public static decimal? Min<TSource> (this IEnumerable<TSource> source,
1785 Func<TSource, decimal?> selector)
1787 if (source == null || selector == null)
1788 throw new ArgumentNullException ();
1790 bool onlyNull = true;
1791 decimal? minimum = decimal.MaxValue;
1792 foreach (TSource item in source) {
1793 decimal? element = selector (item);
1794 if (element.HasValue) {
1796 if (element < minimum)
1800 return (onlyNull ? null : minimum);
1804 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source,
1805 Func<TSource, TResult> selector)
1807 if (source == null || selector == null)
1808 throw new ArgumentNullException ();
1810 bool notAssigned = true;
1811 TResult minimum = default (TResult);
1813 foreach (TSource item in source) {
1814 TResult element = selector (item);
1817 notAssigned = false;
1820 if (element is IComparable<TResult>)
1821 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1822 else if (element is System.IComparable)
1823 comparison = ((System.IComparable) element).CompareTo (minimum);
1825 throw new ArgumentNullException ();
1834 throw new InvalidOperationException ();
1843 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1846 throw new ArgumentNullException ();
1848 foreach (object element in source)
1849 if (element is TResult)
1850 yield return (TResult) element;
1857 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1858 Func<TSource, TKey> keySelector)
1860 return OrderBy<TSource, TKey> (source, keySelector, null);
1864 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1865 Func<TSource, TKey> keySelector,
1866 IComparer<TKey> comparer)
1868 if (source == null || keySelector == null)
1869 throw new ArgumentNullException ();
1871 return new InternalOrderedSequence<TSource, TKey> (
1872 source, keySelector, comparer, false);
1877 #region OrderByDescending
1879 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1880 Func<TSource, TKey> keySelector)
1882 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1886 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1887 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1889 if (source == null || keySelector == null)
1890 throw new ArgumentNullException ();
1892 return new InternalOrderedSequence<TSource, TKey> (
1893 source, keySelector, comparer, true);
1900 public static IEnumerable<int> Range (int start, int count)
1902 if (count < 0 || (start + count - 1) > int.MaxValue)
1903 throw new ArgumentOutOfRangeException ();
1905 for (int i = start; i < (start + count - 1); i++)
1913 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1916 throw new ArgumentOutOfRangeException ();
1918 for (int i = 0; i < count; i++)
1919 yield return element;
1927 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1930 throw new ArgumentNullException ();
1932 List<TSource> list = new List<TSource> (source);
1941 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1942 Func<TSource, TResult> selector)
1944 if (source == null || selector == null)
1945 throw new ArgumentNullException ();
1947 foreach (TSource element in source)
1948 yield return selector (element);
1952 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1953 Func<TSource, int, TResult> selector)
1955 if (source == null || selector == null)
1956 throw new ArgumentNullException ();
1959 foreach (TSource element in source) {
1960 yield return selector (element, counter);
1969 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1970 Func<TSource, IEnumerable<TResult>> selector)
1972 if (source == null || selector == null)
1973 throw new ArgumentNullException ();
1975 foreach (TSource element in source)
1976 foreach (TResult item in selector (element))
1981 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1982 Func<TSource, int, IEnumerable<TResult>> selector)
1984 if (source == null || selector == null)
1985 throw new ArgumentNullException ();
1988 foreach (TSource element in source) {
1989 foreach (TResult item in selector (element, counter++))
1995 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1996 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1998 if (source == null || collectionSelector == null || selector == null)
1999 throw new ArgumentNullException ();
2001 foreach (TSource element in source)
2002 foreach (TCollection collection in collectionSelector (element))
2003 yield return selector (element, collection);
2006 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
2007 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2009 if (source == null || collectionSelector == null || selector == null)
2010 throw new ArgumentNullException ();
2013 foreach (TSource element in source)
2014 foreach (TCollection collection in collectionSelector (element, counter++))
2015 yield return selector (element, collection);
2022 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2025 throw new ArgumentNullException ();
2027 bool otherElement = false;
2028 TSource singleElement = default (TSource);
2029 foreach (TSource element in source) {
2030 if (otherElement) throw new InvalidOperationException ();
2031 if (!otherElement) otherElement = true;
2032 singleElement = element;
2036 return singleElement;
2038 throw new InvalidOperationException ();
2042 public static TSource Single<TSource> (this IEnumerable<TSource> source,
2043 Func<TSource, bool> predicate)
2045 if (source == null || predicate == null)
2046 throw new ArgumentNullException ();
2048 bool otherElement = false;
2049 TSource singleElement = default (TSource);
2050 foreach (TSource element in source) {
2051 if (predicate (element)) {
2052 if (otherElement) throw new InvalidOperationException ();
2053 if (!otherElement) otherElement = true;
2054 singleElement = element;
2059 return singleElement;
2061 throw new InvalidOperationException ();
2066 #region SingleOrDefault
2068 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2071 throw new ArgumentNullException ();
2073 bool otherElement = false;
2074 TSource singleElement = default (TSource);
2075 foreach (TSource element in source) {
2076 if (otherElement) throw new InvalidOperationException ();
2077 if (!otherElement) otherElement = true;
2078 singleElement = element;
2081 return singleElement;
2085 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source,
2086 Func<TSource, bool> predicate)
2088 if (source == null || predicate == null)
2089 throw new ArgumentNullException ();
2091 bool otherElement = false;
2092 TSource singleElement = default (TSource);
2093 foreach (TSource element in source) {
2094 if (predicate (element)) {
2095 if (otherElement) throw new InvalidOperationException ();
2096 if (!otherElement) otherElement = true;
2097 singleElement = element;
2101 return singleElement;
2107 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2110 throw new NotSupportedException ();
2113 foreach (TSource e in source) {
2124 public static IEnumerable<TSource> SkipWhile<TSource> (
2125 this IEnumerable<TSource> source,
2126 Func<TSource, bool> predicate)
2128 if (source == null || predicate == null)
2129 throw new ArgumentNullException ();
2133 foreach (TSource element in source) {
2135 yield return element;
2137 if (!predicate (element)) {
2138 yield return element;
2145 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source,
2146 Func<TSource, int, bool> predicate)
2148 if (source == null || predicate == null)
2149 throw new ArgumentNullException ();
2154 foreach (TSource element in source) {
2156 yield return element;
2158 if (!predicate (element, counter)) {
2159 yield return element;
2170 public static int Sum (this IEnumerable<int> source)
2173 throw new ArgumentNullException ("source");
2176 foreach (int element in source)
2183 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2185 if (source == null || selector == null)
2186 throw new ArgumentNullException ();
2189 foreach (TSource element in source)
2190 sum += selector (element);
2196 public static int? Sum (this IEnumerable<int?> source)
2199 throw new ArgumentNullException ();
2202 foreach (int? element in source)
2203 if (element.HasValue)
2204 sum += element.Value;
2210 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2212 if (source == null || selector == null)
2213 throw new ArgumentNullException ();
2216 foreach (TSource element in source) {
2217 int? item = selector (element);
2226 public static long Sum (this IEnumerable<long> source)
2229 throw new ArgumentNullException ();
2232 foreach (long element in source)
2239 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2241 if (source == null || selector == null)
2242 throw new ArgumentNullException ();
2245 foreach (TSource element in source)
2246 sum += selector (element);
2252 public static long? Sum (this IEnumerable<long?> source)
2255 throw new ArgumentNullException ();
2258 foreach (long? element in source)
2259 if (element.HasValue)
2260 sum += element.Value;
2266 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2268 if (source == null || selector == null)
2269 throw new ArgumentNullException ();
2272 foreach (TSource element in source) {
2273 long? item = selector (element);
2282 public static double Sum (this IEnumerable<double> source)
2285 throw new ArgumentNullException ();
2288 foreach (double element in source)
2295 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2297 if (source == null || selector == null)
2298 throw new ArgumentNullException ();
2301 foreach (TSource element in source)
2302 sum += selector (element);
2308 public static double? Sum (this IEnumerable<double?> source)
2311 throw new ArgumentNullException ();
2314 foreach (double? element in source)
2315 if (element.HasValue)
2316 sum += element.Value;
2322 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2324 if (source == null || selector == null)
2325 throw new ArgumentNullException ();
2328 foreach (TSource element in source) {
2329 double? item = selector (element);
2338 public static decimal Sum (this IEnumerable<decimal> source)
2341 throw new ArgumentNullException ();
2344 foreach (decimal element in source)
2351 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2353 if (source == null || selector == null)
2354 throw new ArgumentNullException ();
2357 foreach (TSource element in source)
2358 sum += selector (element);
2364 public static decimal? Sum (this IEnumerable<decimal?> source)
2367 throw new ArgumentNullException ();
2370 foreach (decimal? element in source)
2371 if (element.HasValue)
2372 sum += element.Value;
2378 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2380 if (source == null || selector == null)
2381 throw new ArgumentNullException ();
2384 foreach (TSource element in source) {
2385 decimal? item = selector (element);
2396 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2399 throw new ArgumentNullException ();
2405 foreach (TSource element in source) {
2406 yield return element;
2408 if (counter == count)
2418 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2420 if (source == null || predicate == null)
2421 throw new ArgumentNullException ();
2423 foreach (TSource element in source) {
2424 if (predicate (element))
2425 yield return element;
2431 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2433 if (source == null || predicate == null)
2434 throw new ArgumentNullException ();
2437 foreach (TSource element in source) {
2438 if (predicate (element, counter))
2439 yield return element;
2450 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2452 return ThenBy<TSource, TKey> (source, keySelector, null);
2456 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2457 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2459 if (source == null || keySelector == null)
2460 throw new ArgumentNullException ();
2462 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2467 #region ThenByDescending
2469 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2470 Func<TSource, TKey> keySelector)
2472 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2476 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2477 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2479 if (source == null || keySelector == null)
2480 throw new ArgumentNullException ();
2482 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2488 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2491 throw new ArgumentNullException ();
2493 List<TSource> list = new List<TSource> (source);
2494 return list.ToArray ();
2499 #region ToDictionary
2500 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2502 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2506 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2509 throw new ArgumentNullException ("source");
2510 if (keySelector == null)
2511 throw new ArgumentNullException ("keySelector");
2512 if (elementSelector == null)
2513 throw new ArgumentNullException ("elementSelector");
2515 Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement> (comparer);
2516 foreach (TSource e in source) {
2517 dict.Add (keySelector (e), elementSelector (e));
2525 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2528 throw new ArgumentNullException ("source");
2530 return new List<TSource> (source);
2536 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2538 return ToLookup<TSource, TKey> (source, keySelector, null);
2542 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2543 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2545 if (source == null || keySelector == null)
2546 throw new ArgumentNullException ();
2548 Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2549 foreach (TSource element in source) {
2550 TKey key = keySelector (element);
2552 throw new ArgumentNullException ();
2553 if (!dictionary.ContainsKey (key))
2554 dictionary.Add (key, new List<TSource> ());
2555 dictionary [key].Add (element);
2557 return new Lookup<TKey, TSource> (dictionary);
2561 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2562 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2564 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2568 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2569 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2571 if (source == null || keySelector == null || elementSelector == null)
2572 throw new ArgumentNullException ();
2574 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2575 foreach (TSource element in source) {
2576 TKey key = keySelector (element);
2578 throw new ArgumentNullException ();
2579 if (!dictionary.ContainsKey (key))
2580 dictionary.Add (key, new List<TElement> ());
2581 dictionary [key].Add (elementSelector (element));
2583 return new Lookup<TKey, TElement> (dictionary);
2590 public static IEnumerable<T> ToSequence<T> (this IEnumerable<T> source)
2592 return (IEnumerable<T>) source;
2600 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2602 if (first == null || second == null)
2603 throw new ArgumentNullException ();
2605 List<TSource> items = new List<TSource> ();
2606 foreach (TSource element in first) {
2607 if (IndexOf (items, element) == -1) {
2608 items.Add (element);
2609 yield return element;
2612 foreach (TSource element in second) {
2613 if (IndexOf (items, element) == -1) {
2614 items.Add (element);
2615 yield return element;
2624 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2625 Func<TSource, bool> predicate)
2627 if (source == null || predicate == null)
2628 throw new ArgumentNullException ();
2630 foreach (TSource element in source)
2631 if (predicate (element))
2632 yield return element;
2636 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2637 Func<TSource, int, bool> predicate)
2639 if (source == null || predicate == null)
2640 throw new ArgumentNullException ();
2643 foreach (TSource element in source) {
2644 if (predicate (element, counter))
2645 yield return element;
2652 // These methods are not included in the
2653 // .NET Standard Query Operators Specification,
2654 // but they provide additional useful commands
2658 private static bool Equals<T> (T first, T second)
2660 // Mostly, values in Enumerable<T>
2661 // sequences need to be compared using
2662 // Equals and GetHashCode
2664 if (first == null || second == null)
2665 return (first == null && second == null);
2667 return ((first.Equals (second) ||
2668 first.GetHashCode () == second.GetHashCode ()));
2675 static int IndexOf<T> (this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2677 if (comparer == null)
2678 comparer = EqualityComparer<T>.Default;
2681 foreach (T element in source) {
2682 if (comparer.Equals (element, item))
2686 // The item was not found
2690 static int IndexOf<T> (this IEnumerable<T> source, T item)
2692 return IndexOf<T> (source, item, null);
2696 #region ToReadOnlyCollection
2697 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (IEnumerable<TSource> source)
2700 return new ReadOnlyCollection<TSource> (new List<TSource> ());
2702 if (typeof (ReadOnlyCollection<TSource>).IsInstanceOfType (source))
2703 return source as ReadOnlyCollection<TSource>;
2705 return new ReadOnlyCollection<TSource> (ToArray<TSource> (source));