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)
529 return DefaultIfEmpty (source, default (TSource));
533 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
536 throw new ArgumentNullException ("source");
539 foreach (TSource item in source) {
545 yield return defaultValue;
552 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
554 return Distinct<TSource> (source, null);
557 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
560 throw new ArgumentNullException ();
562 if (comparer == null)
563 comparer = EqualityComparer<TSource>.Default;
565 List<TSource> items = new List<TSource> ();
566 foreach (TSource element in source) {
567 if (!Contains (items, element, comparer)) {
569 yield return element;
577 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
580 throw new ArgumentNullException ();
582 throw new ArgumentOutOfRangeException ();
584 if (source is IList<TSource>)
585 return ((IList<TSource>) source) [index];
588 foreach (TSource element in source) {
589 if (counter == index)
593 throw new ArgumentOutOfRangeException ();
599 #region ElementAtOrDefault
601 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
604 throw new ArgumentNullException ();
606 return default (TSource);
608 if (source is IList<TSource>) {
609 if (((IList<TSource>) source).Count >= index)
610 return default (TSource);
612 return ((IList<TSource>) source) [index];
615 foreach (TSource element in source) {
616 if (counter == index)
620 return default (TSource);
627 public static IEnumerable<TResult> Empty<TResult> ()
629 return new List<TResult> ();
635 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
637 return Except (first, second, null);
640 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
642 if (first == null || second == null)
643 throw new ArgumentNullException ();
645 if (comparer == null)
646 comparer = EqualityComparer<TSource>.Default;
648 List<TSource> items = new List<TSource> (Distinct (second));
649 foreach (TSource element in first) {
650 if (!Contains (items, element, comparer))
651 yield return element;
659 public static TSource First<TSource> (this IEnumerable<TSource> source)
662 throw new ArgumentNullException ();
664 foreach (TSource element in source)
667 throw new InvalidOperationException ();
671 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
673 if (source == null || predicate == null)
674 throw new ArgumentNullException ();
676 foreach (TSource element in source) {
677 if (predicate (element))
681 throw new InvalidOperationException ();
686 #region FirstOrDefault
688 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
691 throw new ArgumentNullException ();
693 foreach (TSource element in source)
696 return default (TSource);
700 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
702 if (source == null || predicate == null)
703 throw new ArgumentNullException ();
705 foreach (TSource element in source) {
706 if (predicate (element))
710 return default (TSource);
717 private static List<T> ContainsGroup<K, T> (
718 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
720 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
721 foreach (KeyValuePair<K, List<T>> value in items) {
722 if (comparerInUse.Equals (value.Key, key))
729 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
730 Func<TSource, TKey> keySelector)
732 return GroupBy<TSource, TKey> (source, keySelector, null);
736 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
737 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
739 if (source == null || keySelector == null)
740 throw new ArgumentNullException ();
742 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
743 List<TSource> nullList = new List<TSource> ();
745 int nullCounter = -1;
747 foreach (TSource element in source) {
748 TKey key = keySelector (element);
750 nullList.Add (element);
751 if (nullCounter == -1) {
752 nullCounter = counter;
756 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
758 group = new List<TSource> ();
759 groups.Add (key, group);
767 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
768 if (counter == nullCounter) {
769 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
770 yield return nullGroup;
773 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
774 yield return grouping;
780 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
781 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
783 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
787 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
788 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
790 if (source == null || keySelector == null || elementSelector == null)
791 throw new ArgumentNullException ();
793 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
794 List<TElement> nullList = new List<TElement> ();
796 int nullCounter = -1;
798 foreach (TSource item in source) {
799 TKey key = keySelector (item);
800 TElement element = elementSelector (item);
802 nullList.Add (element);
803 if (nullCounter == -1) {
804 nullCounter = counter;
808 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
810 group = new List<TElement> ();
811 groups.Add (key, group);
819 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
820 if (counter == nullCounter) {
821 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
822 yield return nullGroup;
825 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
826 yield return grouping;
835 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
836 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
837 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
839 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
842 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
843 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
844 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
845 IEqualityComparer<TKey> comparer)
847 if (outer == null || inner == null || outerKeySelector == null ||
848 innerKeySelector == null || resultSelector == null)
849 throw new ArgumentNullException ();
851 if (comparer == null)
852 comparer = EqualityComparer<TKey>.Default;
854 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
855 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
856 foreach (U element in inner)
858 K innerKey = innerKeySelector (element);
859 if (!innerKeys.ContainsKey (innerKey))
860 innerKeys.Add (innerKey, new List<U> ());
861 innerKeys[innerKey].Add (element);
864 foreach (TOuter element in outer) {
865 TKey outerKey = outerKeySelector (element);
866 if (innerKeys.Contains (outerKey))
867 yield return resultSelector (element, innerKeys [outerKey]);
869 yield return resultSelector (element, Empty<TInner> ());
878 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
880 if (first == null || second == null)
881 throw new ArgumentNullException ();
883 List<TSource> items = new List<TSource> (Distinct (first));
884 bool [] marked = new bool [items.Count];
885 for (int i = 0; i < marked.Length; i++)
888 foreach (TSource element in second) {
889 int index = IndexOf (items, element);
891 marked [index] = true;
893 for (int i = 0; i < marked.Length; i++) {
895 yield return items [i];
903 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
904 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
905 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
907 if (outer == null || inner == null || outerKeySelector == null ||
908 innerKeySelector == null || resultSelector == null)
909 throw new ArgumentNullException ();
911 if (comparer == null)
912 comparer = EqualityComparer<TKey>.Default;
914 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
915 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
916 foreach (U element in inner)
918 K innerKey = innerKeySelector (element);
919 if (!innerKeys.ContainsKey (innerKey))
920 innerKeys.Add (innerKey, new List<U> ());
921 innerKeys[innerKey].Add (element);
924 foreach (TOuter element in outer) {
925 TKey outerKey = outerKeySelector (element);
926 if (innerKeys.Contains (outerKey)) {
927 foreach (TInner innerElement in innerKeys [outerKey])
928 yield return resultSelector (element, innerElement);
933 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
934 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
935 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
937 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
943 public static TSource Last<TSource> (this IEnumerable<TSource> source)
946 throw new ArgumentNullException ();
948 bool noElements = true;
949 TSource lastElement = default (TSource);
950 foreach (TSource element in source) {
951 if (noElements) noElements = false;
952 lastElement = element;
958 throw new InvalidOperationException ();
961 public static TSource Last<TSource> (this IEnumerable<TSource> source,
962 Func<TSource, bool> predicate)
964 if (source == null || predicate == null)
965 throw new ArgumentNullException ();
967 bool noElements = true;
968 TSource lastElement = default (TSource);
969 foreach (TSource element in source) {
970 if (predicate (element)) {
971 if (noElements) noElements = false;
972 lastElement = element;
979 throw new InvalidOperationException ();
984 #region LastOrDefault
986 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
989 throw new ArgumentNullException ();
991 TSource lastElement = default (TSource);
992 foreach (TSource element in source)
993 lastElement = element;
998 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source,
999 Func<TSource, bool> predicate)
1001 if (source == null || predicate == null)
1002 throw new ArgumentNullException ();
1004 TSource lastElement = default (TSource);
1005 foreach (TSource element in source) {
1006 if (predicate (element))
1007 lastElement = element;
1016 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1019 throw new ArgumentNullException ();
1022 foreach (TSource element in source)
1028 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1030 if (source == null || selector == null)
1031 throw new ArgumentNullException ();
1034 foreach (TSource element in source)
1035 if (selector (element))
1045 public static int Max (this IEnumerable<int> source)
1048 throw new ArgumentNullException ();
1050 int maximum = int.MinValue;
1052 foreach (int element in source) {
1053 if (element > maximum)
1059 throw new InvalidOperationException ();
1065 public static int? Max (this IEnumerable<int?> source)
1068 throw new ArgumentNullException ();
1070 bool onlyNull = true;
1071 int? maximum = int.MinValue;
1072 foreach (int? element in source) {
1073 if (element.HasValue) {
1075 if (element > maximum)
1079 return (onlyNull ? null : maximum);
1083 public static long Max (this IEnumerable<long> source)
1086 throw new ArgumentNullException ();
1088 long maximum = long.MinValue;
1090 foreach (long element in source) {
1091 if (element > maximum)
1097 throw new InvalidOperationException ();
1103 public static long? Max (this IEnumerable<long?> source)
1106 throw new ArgumentNullException ();
1108 bool onlyNull = true;
1109 long? maximum = long.MinValue;
1110 foreach (long? element in source) {
1111 if (element.HasValue) {
1113 if (element > maximum)
1117 return (onlyNull ? null : maximum);
1121 public static double Max (this IEnumerable<double> source)
1124 throw new ArgumentNullException ();
1126 double maximum = double.MinValue;
1128 foreach (double element in source) {
1129 if (element > maximum)
1135 throw new InvalidOperationException ();
1141 public static double? Max (this IEnumerable<double?> source)
1144 throw new ArgumentNullException ();
1146 bool onlyNull = true;
1147 double? maximum = double.MinValue;
1148 foreach (double? element in source) {
1149 if (element.HasValue) {
1151 if (element > maximum)
1155 return (onlyNull ? null : maximum);
1159 public static decimal Max (this IEnumerable<decimal> source)
1162 throw new ArgumentNullException ();
1164 decimal maximum = decimal.MinValue;
1166 foreach (decimal element in source) {
1167 if (element > maximum)
1173 throw new InvalidOperationException ();
1179 public static decimal? Max (this IEnumerable<decimal?> source)
1182 throw new ArgumentNullException ();
1184 bool onlyNull = true;
1185 decimal? maximum = decimal.MinValue;
1186 foreach (decimal? element in source) {
1187 if (element.HasValue) {
1189 if (element > maximum)
1193 return (onlyNull ? null : maximum);
1197 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1200 throw new ArgumentNullException ();
1202 bool notAssigned = true;
1203 TSource maximum = default (TSource);
1205 foreach (TSource element in source) {
1208 notAssigned = false;
1211 if (element is IComparable<TSource>)
1212 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1213 else if (element is System.IComparable)
1214 comparison = ((System.IComparable) element).CompareTo (maximum);
1216 throw new ArgumentNullException ();
1225 throw new InvalidOperationException ();
1231 public static int Max<TSource> (this IEnumerable<TSource> source,
1232 Func<TSource, int> selector)
1234 if (source == null || selector == null)
1235 throw new ArgumentNullException ();
1237 int maximum = int.MinValue;
1239 foreach (TSource item in source) {
1240 int element = selector (item);
1241 if (element > maximum)
1247 throw new InvalidOperationException ();
1253 public static int? Max<TSource> (this IEnumerable<TSource> source,
1254 Func<TSource, int?> selector)
1256 if (source == null || selector == null)
1257 throw new ArgumentNullException ();
1259 bool onlyNull = true;
1260 int? maximum = int.MinValue;
1261 foreach (TSource item in source) {
1262 int? element = selector (item);
1263 if (element.HasValue) {
1265 if (element > maximum)
1269 return (onlyNull ? null : maximum);
1273 public static long Max<TSource> (this IEnumerable<TSource> source,
1274 Func<TSource, long> selector)
1276 if (source == null || selector == null)
1277 throw new ArgumentNullException ();
1279 long maximum = long.MinValue;
1281 foreach (TSource item in source) {
1282 long element = selector (item);
1283 if (element > maximum)
1289 throw new InvalidOperationException ();
1295 public static long? Max<TSource> (this IEnumerable<TSource> source,
1296 Func<TSource, long?> selector)
1298 if (source == null || selector == null)
1299 throw new ArgumentNullException ();
1301 bool onlyNull = true;
1302 long? maximum = long.MinValue;
1303 foreach (TSource item in source) {
1304 long? element = selector (item);
1305 if (element.HasValue) {
1307 if (element > maximum)
1311 return (onlyNull ? null : maximum);
1315 public static double Max<TSource> (this IEnumerable<TSource> source,
1316 Func<TSource, double> selector)
1318 if (source == null || selector == null)
1319 throw new ArgumentNullException ();
1321 double maximum = double.MinValue;
1323 foreach (TSource item in source) {
1324 double element = selector (item);
1325 if (element > maximum)
1331 throw new InvalidOperationException ();
1337 public static double? Max<TSource> (this IEnumerable<TSource> source,
1338 Func<TSource, double?> selector)
1340 if (source == null || selector == null)
1341 throw new ArgumentNullException ();
1343 bool onlyNull = true;
1344 double? maximum = double.MinValue;
1345 foreach (TSource item in source) {
1346 double? element = selector (item);
1347 if (element.HasValue) {
1349 if (element > maximum)
1353 return (onlyNull ? null : maximum);
1357 public static decimal Max<TSource> (this IEnumerable<TSource> source,
1358 Func<TSource, decimal> selector)
1360 if (source == null || selector == null)
1361 throw new ArgumentNullException ();
1363 decimal maximum = decimal.MinValue;
1365 foreach (TSource item in source) {
1366 decimal element = selector (item);
1367 if (element > maximum)
1373 throw new InvalidOperationException ();
1379 public static decimal? Max<TSource> (this IEnumerable<TSource> source,
1380 Func<TSource, decimal?> selector)
1382 if (source == null || selector == null)
1383 throw new ArgumentNullException ();
1385 bool onlyNull = true;
1386 decimal? maximum = decimal.MinValue;
1387 foreach (TSource item in source) {
1388 decimal? element = selector (item);
1389 if (element.HasValue) {
1391 if (element > maximum)
1395 return (onlyNull ? null : maximum);
1399 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source,
1400 Func<TSource, TResult> selector)
1402 if (source == null || selector == null)
1403 throw new ArgumentNullException ();
1405 bool notAssigned = true;
1406 TResult maximum = default (TResult);
1408 foreach (TSource item in source) {
1409 TResult element = selector (item);
1412 notAssigned = false;
1415 if (element is IComparable<TResult>)
1416 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1417 else if (element is System.IComparable)
1418 comparison = ((System.IComparable) element).CompareTo (maximum);
1420 throw new ArgumentNullException ();
1429 throw new InvalidOperationException ();
1438 public static int Min (this IEnumerable<int> source)
1441 throw new ArgumentNullException ();
1443 int minimum = int.MaxValue;
1445 foreach (int element in source) {
1446 if (element < minimum)
1452 throw new InvalidOperationException ();
1458 public static int? Min (this IEnumerable<int?> source)
1461 throw new ArgumentNullException ();
1463 bool onlyNull = true;
1464 int? minimum = int.MaxValue;
1465 foreach (int? element in source) {
1466 if (element.HasValue) {
1468 if (element < minimum)
1472 return (onlyNull ? null : minimum);
1475 public static long Min (this IEnumerable<long> source)
1478 throw new ArgumentNullException ();
1480 long minimum = long.MaxValue;
1482 foreach (long element in source) {
1483 if (element < minimum)
1489 throw new InvalidOperationException ();
1495 public static long? Min (this IEnumerable<long?> source)
1498 throw new ArgumentNullException ();
1500 bool onlyNull = true;
1501 long? minimum = long.MaxValue;
1502 foreach (long? element in source) {
1503 if (element.HasValue) {
1505 if (element < minimum)
1509 return (onlyNull ? null : minimum);
1513 public static double Min (this IEnumerable<double> source)
1516 throw new ArgumentNullException ();
1518 double minimum = double.MaxValue;
1520 foreach (double element in source) {
1521 if (element < minimum)
1527 throw new InvalidOperationException ();
1533 public static double? Min (this IEnumerable<double?> source)
1536 throw new ArgumentNullException ();
1538 bool onlyNull = true;
1539 double? minimum = double.MaxValue;
1540 foreach (double? element in source) {
1541 if (element.HasValue) {
1543 if (element < minimum)
1547 return (onlyNull ? null : minimum);
1551 public static decimal Min (this IEnumerable<decimal> source)
1554 throw new ArgumentNullException ();
1556 decimal minimum = decimal.MaxValue;
1558 foreach (decimal element in source) {
1559 if (element < minimum)
1565 throw new InvalidOperationException ();
1571 public static decimal? Min (this IEnumerable<decimal?> source)
1574 throw new ArgumentNullException ();
1576 bool onlyNull = true;
1577 decimal? minimum = decimal.MaxValue;
1578 foreach (decimal? element in source) {
1579 if (element.HasValue) {
1581 if (element < minimum)
1585 return (onlyNull ? null : minimum);
1589 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1592 throw new ArgumentNullException ();
1594 bool notAssigned = true;
1595 TSource minimum = default (TSource);
1597 foreach (TSource element in source) {
1600 notAssigned = false;
1603 if (element is IComparable<TSource>)
1604 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1605 else if (element is System.IComparable)
1606 comparison = ((System.IComparable) element).CompareTo (minimum);
1608 throw new ArgumentNullException ();
1617 throw new InvalidOperationException ();
1623 public static int Min<TSource> (this IEnumerable<TSource> source,
1624 Func<TSource, int> selector)
1626 if (source == null || selector == null)
1627 throw new ArgumentNullException ();
1629 int minimum = int.MaxValue;
1631 foreach (TSource item in source) {
1632 int element = selector (item);
1633 if (element < minimum)
1639 throw new InvalidOperationException ();
1645 public static int? Min<TSource> (this IEnumerable<TSource> source,
1646 Func<TSource, int?> selector)
1648 if (source == null || selector == null)
1649 throw new ArgumentNullException ();
1651 bool onlyNull = true;
1652 int? minimum = int.MaxValue;
1653 foreach (TSource item in source) {
1654 int? element = selector (item);
1655 if (element.HasValue) {
1657 if (element < minimum)
1661 return (onlyNull ? null : minimum);
1665 public static long Min<TSource> (this IEnumerable<TSource> source,
1666 Func<TSource, long> selector)
1668 if (source == null || selector == null)
1669 throw new ArgumentNullException ();
1671 long minimum = long.MaxValue;
1673 foreach (TSource item in source) {
1674 long element = selector (item);
1675 if (element < minimum)
1681 throw new InvalidOperationException ();
1687 public static long? Min<TSource> (this IEnumerable<TSource> source,
1688 Func<TSource, long?> selector)
1690 if (source == null || selector == null)
1691 throw new ArgumentNullException ();
1693 bool onlyNull = true;
1694 long? minimum = long.MaxValue;
1695 foreach (TSource item in source) {
1696 long? element = selector (item);
1697 if (element.HasValue) {
1699 if (element < minimum)
1703 return (onlyNull ? null : minimum);
1707 public static double Min<TSource> (this IEnumerable<TSource> source,
1708 Func<TSource, double> selector)
1710 if (source == null || selector == null)
1711 throw new ArgumentNullException ();
1713 double minimum = double.MaxValue;
1715 foreach (TSource item in source) {
1716 double element = selector (item);
1717 if (element < minimum)
1723 throw new InvalidOperationException ();
1729 public static double? Min<TSource> (this IEnumerable<TSource> source,
1730 Func<TSource, double?> selector)
1732 if (source == null || selector == null)
1733 throw new ArgumentNullException ();
1735 bool onlyNull = true;
1736 double? minimum = double.MaxValue;
1737 foreach (TSource item in source) {
1738 double? element = selector (item);
1739 if (element.HasValue) {
1741 if (element < minimum)
1745 return (onlyNull ? null : minimum);
1749 public static decimal Min<TSource> (this IEnumerable<TSource> source,
1750 Func<TSource, decimal> selector)
1752 if (source == null || selector == null)
1753 throw new ArgumentNullException ();
1755 decimal minimum = decimal.MaxValue;
1757 foreach (TSource item in source) {
1758 decimal element = selector (item);
1759 if (element < minimum)
1765 throw new InvalidOperationException ();
1771 public static decimal? Min<TSource> (this IEnumerable<TSource> source,
1772 Func<TSource, decimal?> selector)
1774 if (source == null || selector == null)
1775 throw new ArgumentNullException ();
1777 bool onlyNull = true;
1778 decimal? minimum = decimal.MaxValue;
1779 foreach (TSource item in source) {
1780 decimal? element = selector (item);
1781 if (element.HasValue) {
1783 if (element < minimum)
1787 return (onlyNull ? null : minimum);
1791 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source,
1792 Func<TSource, TResult> selector)
1794 if (source == null || selector == null)
1795 throw new ArgumentNullException ();
1797 bool notAssigned = true;
1798 TResult minimum = default (TResult);
1800 foreach (TSource item in source) {
1801 TResult element = selector (item);
1804 notAssigned = false;
1807 if (element is IComparable<TResult>)
1808 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1809 else if (element is System.IComparable)
1810 comparison = ((System.IComparable) element).CompareTo (minimum);
1812 throw new ArgumentNullException ();
1821 throw new InvalidOperationException ();
1830 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1833 throw new ArgumentNullException ();
1835 foreach (object element in source)
1836 if (element is TResult)
1837 yield return (TResult) element;
1844 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1845 Func<TSource, TKey> keySelector)
1847 return OrderBy<TSource, TKey> (source, keySelector, null);
1851 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1852 Func<TSource, TKey> keySelector,
1853 IComparer<TKey> comparer)
1855 if (source == null || keySelector == null)
1856 throw new ArgumentNullException ();
1858 return new InternalOrderedSequence<TSource, TKey> (
1859 source, keySelector, comparer, false);
1864 #region OrderByDescending
1866 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1867 Func<TSource, TKey> keySelector)
1869 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1873 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1874 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1876 if (source == null || keySelector == null)
1877 throw new ArgumentNullException ();
1879 return new InternalOrderedSequence<TSource, TKey> (
1880 source, keySelector, comparer, true);
1887 public static IEnumerable<int> Range (int start, int count)
1889 if (count < 0 || (start + count - 1) > int.MaxValue)
1890 throw new ArgumentOutOfRangeException ();
1892 for (int i = start; i < (start + count - 1); i++)
1900 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1903 throw new ArgumentOutOfRangeException ();
1905 for (int i = 0; i < count; i++)
1906 yield return element;
1914 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1917 throw new ArgumentNullException ();
1919 List<TSource> list = new List<TSource> (source);
1928 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1929 Func<TSource, TResult> selector)
1931 if (source == null || selector == null)
1932 throw new ArgumentNullException ();
1934 foreach (TSource element in source)
1935 yield return selector (element);
1939 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1940 Func<TSource, int, TResult> selector)
1942 if (source == null || selector == null)
1943 throw new ArgumentNullException ();
1946 foreach (TSource element in source) {
1947 yield return selector (element, counter);
1956 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1957 Func<TSource, IEnumerable<TResult>> selector)
1959 if (source == null || selector == null)
1960 throw new ArgumentNullException ();
1962 foreach (TSource element in source)
1963 foreach (TResult item in selector (element))
1968 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1969 Func<TSource, int, IEnumerable<TResult>> selector)
1971 if (source == null || selector == null)
1972 throw new ArgumentNullException ();
1975 foreach (TSource element in source) {
1976 foreach (TResult item in selector (element, counter++))
1982 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1983 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1985 if (source == null || collectionSelector == null || selector == null)
1986 throw new ArgumentNullException ();
1988 foreach (TSource element in source)
1989 foreach (TCollection collection in collectionSelector (element))
1990 yield return selector (element, collection);
1993 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1994 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1996 if (source == null || collectionSelector == null || selector == null)
1997 throw new ArgumentNullException ();
2000 foreach (TSource element in source)
2001 foreach (TCollection collection in collectionSelector (element, counter++))
2002 yield return selector (element, collection);
2009 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2012 throw new ArgumentNullException ();
2014 bool otherElement = false;
2015 TSource singleElement = default (TSource);
2016 foreach (TSource element in source) {
2017 if (otherElement) throw new InvalidOperationException ();
2018 if (!otherElement) otherElement = true;
2019 singleElement = element;
2023 return singleElement;
2025 throw new InvalidOperationException ();
2029 public static TSource Single<TSource> (this IEnumerable<TSource> source,
2030 Func<TSource, bool> predicate)
2032 if (source == null || predicate == null)
2033 throw new ArgumentNullException ();
2035 bool otherElement = false;
2036 TSource singleElement = default (TSource);
2037 foreach (TSource element in source) {
2038 if (predicate (element)) {
2039 if (otherElement) throw new InvalidOperationException ();
2040 if (!otherElement) otherElement = true;
2041 singleElement = element;
2046 return singleElement;
2048 throw new InvalidOperationException ();
2053 #region SingleOrDefault
2055 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2058 throw new ArgumentNullException ();
2060 bool otherElement = false;
2061 TSource singleElement = default (TSource);
2062 foreach (TSource element in source) {
2063 if (otherElement) throw new InvalidOperationException ();
2064 if (!otherElement) otherElement = true;
2065 singleElement = element;
2068 return singleElement;
2072 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source,
2073 Func<TSource, bool> predicate)
2075 if (source == null || predicate == null)
2076 throw new ArgumentNullException ();
2078 bool otherElement = false;
2079 TSource singleElement = default (TSource);
2080 foreach (TSource element in source) {
2081 if (predicate (element)) {
2082 if (otherElement) throw new InvalidOperationException ();
2083 if (!otherElement) otherElement = true;
2084 singleElement = element;
2088 return singleElement;
2094 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2097 throw new NotSupportedException ();
2100 foreach (TSource e in source) {
2111 public static IEnumerable<TSource> SkipWhile<TSource> (
2112 this IEnumerable<TSource> source,
2113 Func<TSource, bool> predicate)
2115 if (source == null || predicate == null)
2116 throw new ArgumentNullException ();
2120 foreach (TSource element in source) {
2122 yield return element;
2124 if (!predicate (element)) {
2125 yield return element;
2132 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source,
2133 Func<TSource, int, bool> predicate)
2135 if (source == null || predicate == null)
2136 throw new ArgumentNullException ();
2141 foreach (TSource element in source) {
2143 yield return element;
2145 if (!predicate (element, counter)) {
2146 yield return element;
2157 public static int Sum (this IEnumerable<int> source)
2160 throw new ArgumentNullException ("source");
2163 foreach (int element in source)
2170 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2172 if (source == null || selector == null)
2173 throw new ArgumentNullException ();
2176 foreach (TSource element in source)
2177 sum += selector (element);
2183 public static int? Sum (this IEnumerable<int?> source)
2186 throw new ArgumentNullException ();
2189 foreach (int? element in source)
2190 if (element.HasValue)
2191 sum += element.Value;
2197 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2199 if (source == null || selector == null)
2200 throw new ArgumentNullException ();
2203 foreach (TSource element in source) {
2204 int? item = selector (element);
2213 public static long Sum (this IEnumerable<long> source)
2216 throw new ArgumentNullException ();
2219 foreach (long element in source)
2226 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2228 if (source == null || selector == null)
2229 throw new ArgumentNullException ();
2232 foreach (TSource element in source)
2233 sum += selector (element);
2239 public static long? Sum (this IEnumerable<long?> source)
2242 throw new ArgumentNullException ();
2245 foreach (long? element in source)
2246 if (element.HasValue)
2247 sum += element.Value;
2253 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2255 if (source == null || selector == null)
2256 throw new ArgumentNullException ();
2259 foreach (TSource element in source) {
2260 long? item = selector (element);
2269 public static double Sum (this IEnumerable<double> source)
2272 throw new ArgumentNullException ();
2275 foreach (double element in source)
2282 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2284 if (source == null || selector == null)
2285 throw new ArgumentNullException ();
2288 foreach (TSource element in source)
2289 sum += selector (element);
2295 public static double? Sum (this IEnumerable<double?> source)
2298 throw new ArgumentNullException ();
2301 foreach (double? element in source)
2302 if (element.HasValue)
2303 sum += element.Value;
2309 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2311 if (source == null || selector == null)
2312 throw new ArgumentNullException ();
2315 foreach (TSource element in source) {
2316 double? item = selector (element);
2325 public static decimal Sum (this IEnumerable<decimal> source)
2328 throw new ArgumentNullException ();
2331 foreach (decimal element in source)
2338 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2340 if (source == null || selector == null)
2341 throw new ArgumentNullException ();
2344 foreach (TSource element in source)
2345 sum += selector (element);
2351 public static decimal? Sum (this IEnumerable<decimal?> source)
2354 throw new ArgumentNullException ();
2357 foreach (decimal? element in source)
2358 if (element.HasValue)
2359 sum += element.Value;
2365 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2367 if (source == null || selector == null)
2368 throw new ArgumentNullException ();
2371 foreach (TSource element in source) {
2372 decimal? item = selector (element);
2383 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2386 throw new ArgumentNullException ();
2392 foreach (TSource element in source) {
2393 yield return element;
2395 if (counter == count)
2405 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2407 if (source == null || predicate == null)
2408 throw new ArgumentNullException ();
2410 foreach (TSource element in source) {
2411 if (predicate (element))
2412 yield return element;
2418 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2420 if (source == null || predicate == null)
2421 throw new ArgumentNullException ();
2424 foreach (TSource element in source) {
2425 if (predicate (element, counter))
2426 yield return element;
2437 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2439 return ThenBy<TSource, TKey> (source, keySelector, null);
2443 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2444 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2446 if (source == null || keySelector == null)
2447 throw new ArgumentNullException ();
2449 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2454 #region ThenByDescending
2456 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2457 Func<TSource, TKey> keySelector)
2459 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2463 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2464 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2466 if (source == null || keySelector == null)
2467 throw new ArgumentNullException ();
2469 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2475 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2478 throw new ArgumentNullException ();
2480 List<TSource> list = new List<TSource> (source);
2481 return list.ToArray ();
2486 #region ToDictionary
2487 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2489 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2493 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2496 throw new ArgumentNullException ("source");
2497 if (keySelector == null)
2498 throw new ArgumentNullException ("keySelector");
2499 if (elementSelector == null)
2500 throw new ArgumentNullException ("elementSelector");
2502 Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement> (comparer);
2503 foreach (TSource e in source) {
2504 dict.Add (keySelector (e), elementSelector (e));
2512 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2515 throw new ArgumentNullException ("source");
2517 return new List<TSource> (source);
2523 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2525 return ToLookup<TSource, TKey> (source, keySelector, null);
2529 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2530 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2532 if (source == null || keySelector == null)
2533 throw new ArgumentNullException ();
2535 Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2536 foreach (TSource element in source) {
2537 TKey key = keySelector (element);
2539 throw new ArgumentNullException ();
2540 if (!dictionary.ContainsKey (key))
2541 dictionary.Add (key, new List<TSource> ());
2542 dictionary [key].Add (element);
2544 return new Lookup<TKey, TSource> (dictionary);
2548 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2549 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2551 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2555 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2556 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2558 if (source == null || keySelector == null || elementSelector == null)
2559 throw new ArgumentNullException ();
2561 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2562 foreach (TSource element in source) {
2563 TKey key = keySelector (element);
2565 throw new ArgumentNullException ();
2566 if (!dictionary.ContainsKey (key))
2567 dictionary.Add (key, new List<TElement> ());
2568 dictionary [key].Add (elementSelector (element));
2570 return new Lookup<TKey, TElement> (dictionary);
2577 public static IEnumerable<T> ToSequence<T> (this IEnumerable<T> source)
2579 return (IEnumerable<T>) source;
2587 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2589 if (first == null || second == null)
2590 throw new ArgumentNullException ();
2592 List<TSource> items = new List<TSource> ();
2593 foreach (TSource element in first) {
2594 if (IndexOf (items, element) == -1) {
2595 items.Add (element);
2596 yield return element;
2599 foreach (TSource element in second) {
2600 if (IndexOf (items, element) == -1) {
2601 items.Add (element);
2602 yield return element;
2611 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2612 Func<TSource, bool> predicate)
2614 if (source == null || predicate == null)
2615 throw new ArgumentNullException ();
2617 foreach (TSource element in source)
2618 if (predicate (element))
2619 yield return element;
2623 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2624 Func<TSource, int, bool> predicate)
2626 if (source == null || predicate == null)
2627 throw new ArgumentNullException ();
2630 foreach (TSource element in source) {
2631 if (predicate (element, counter))
2632 yield return element;
2639 // These methods are not included in the
2640 // .NET Standard Query Operators Specification,
2641 // but they provide additional useful commands
2645 private static bool Equals<T> (T first, T second)
2647 // Mostly, values in Enumerable<T>
2648 // sequences need to be compared using
2649 // Equals and GetHashCode
2651 if (first == null || second == null)
2652 return (first == null && second == null);
2654 return ((first.Equals (second) ||
2655 first.GetHashCode () == second.GetHashCode ()));
2662 static int IndexOf<T> (this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2664 if (comparer == null)
2665 comparer = EqualityComparer<T>.Default;
2668 foreach (T element in source) {
2669 if (comparer.Equals (element, item))
2673 // The item was not found
2677 static int IndexOf<T> (this IEnumerable<T> source, T item)
2679 return IndexOf<T> (source, item, null);
2683 #region ToReadOnlyCollection
2684 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (IEnumerable<TSource> source)
2687 return new ReadOnlyCollection<TSource> (new List<TSource> ());
2689 if (typeof (ReadOnlyCollection<TSource>).IsInstanceOfType (source))
2690 return source as ReadOnlyCollection<TSource>;
2692 return new ReadOnlyCollection<TSource> (ToArray<TSource> (source));