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 ICollection<TSource> collection = source as ICollection<TSource>;
468 if (collection != null)
469 return collection.Contains (value);
471 return Contains<TSource> (source, value, null);
475 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
478 throw new ArgumentNullException ("source");
480 if (comparer == null)
481 comparer = EqualityComparer<TSource>.Default;
483 foreach (TSource e in source) {
484 if (comparer.Equals (e, value))
493 public static int Count<TSource> (this IEnumerable<TSource> source)
496 throw new ArgumentNullException ();
498 ICollection<TSource> collection = source as ICollection<TSource>;
499 if (collection != null)
500 return collection.Count;
503 foreach (TSource element in source)
508 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
510 if (source == null || selector == null)
511 throw new ArgumentNullException ();
514 foreach (TSource element in source)
515 if (selector (element))
522 #region DefaultIfEmpty
524 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
526 return DefaultIfEmpty (source, default (TSource));
529 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
532 throw new ArgumentNullException ("source");
535 foreach (TSource item in source) {
541 yield return defaultValue;
548 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
550 return Distinct<TSource> (source, null);
553 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
556 throw new ArgumentNullException ();
558 if (comparer == null)
559 comparer = EqualityComparer<TSource>.Default;
561 List<TSource> items = new List<TSource> (); // TODO: use a HashSet here
562 foreach (TSource element in source) {
563 if (!Contains (items, element, comparer)) {
565 yield return element;
573 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
576 throw new ArgumentNullException ();
578 throw new ArgumentOutOfRangeException ();
580 IList<TSource> list = source as IList<TSource>;
585 foreach (TSource element in source) {
586 if (counter == index)
591 throw new ArgumentOutOfRangeException ();
596 #region ElementAtOrDefault
598 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
601 throw new ArgumentNullException ();
603 return default (TSource);
605 IList<TSource> list = source as IList<TSource>;
607 return index < list.Count ? list [index] : default (TSource);
610 foreach (TSource element in source) {
611 if (counter == index)
616 return default (TSource);
622 public static IEnumerable<TResult> Empty<TResult> ()
624 return new List<TResult> ();
630 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
632 return Except (first, second, null);
635 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
637 if (first == null || second == null)
638 throw new ArgumentNullException ();
640 if (comparer == null)
641 comparer = EqualityComparer<TSource>.Default;
643 List<TSource> items = new List<TSource> (Distinct (second));
644 foreach (TSource element in first) {
645 if (!Contains (items, element, comparer))
646 yield return element;
654 public static TSource First<TSource> (this IEnumerable<TSource> source)
657 throw new ArgumentNullException ();
659 foreach (TSource element in source)
662 throw new InvalidOperationException ();
666 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
668 if (source == null || predicate == null)
669 throw new ArgumentNullException ();
671 foreach (TSource element in source) {
672 if (predicate (element))
676 throw new InvalidOperationException ();
681 #region FirstOrDefault
683 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
686 throw new ArgumentNullException ();
688 foreach (TSource element in source)
691 return default (TSource);
695 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
697 if (source == null || predicate == null)
698 throw new ArgumentNullException ();
700 foreach (TSource element in source) {
701 if (predicate (element))
705 return default (TSource);
712 private static List<T> ContainsGroup<K, T> (
713 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
715 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
716 foreach (KeyValuePair<K, List<T>> value in items) {
717 if (comparerInUse.Equals (value.Key, key))
724 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
725 Func<TSource, TKey> keySelector)
727 return GroupBy<TSource, TKey> (source, keySelector, null);
731 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
732 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
734 if (source == null || keySelector == null)
735 throw new ArgumentNullException ();
737 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
738 List<TSource> nullList = new List<TSource> ();
740 int nullCounter = -1;
742 foreach (TSource element in source) {
743 TKey key = keySelector (element);
745 nullList.Add (element);
746 if (nullCounter == -1) {
747 nullCounter = counter;
751 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
753 group = new List<TSource> ();
754 groups.Add (key, group);
762 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
763 if (counter == nullCounter) {
764 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
765 yield return nullGroup;
768 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
769 yield return grouping;
775 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
776 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
778 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
782 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
783 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
785 if (source == null || keySelector == null || elementSelector == null)
786 throw new ArgumentNullException ();
788 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
789 List<TElement> nullList = new List<TElement> ();
791 int nullCounter = -1;
793 foreach (TSource item in source) {
794 TKey key = keySelector (item);
795 TElement element = elementSelector (item);
797 nullList.Add (element);
798 if (nullCounter == -1) {
799 nullCounter = counter;
803 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
805 group = new List<TElement> ();
806 groups.Add (key, group);
814 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
815 if (counter == nullCounter) {
816 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
817 yield return nullGroup;
820 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
821 yield return grouping;
830 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
831 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
832 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
834 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
837 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
838 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
839 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
840 IEqualityComparer<TKey> comparer)
842 if (outer == null || inner == null || outerKeySelector == null ||
843 innerKeySelector == null || resultSelector == null)
844 throw new ArgumentNullException ();
846 if (comparer == null)
847 comparer = EqualityComparer<TKey>.Default;
849 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
850 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
851 foreach (U element in inner)
853 K innerKey = innerKeySelector (element);
854 if (!innerKeys.ContainsKey (innerKey))
855 innerKeys.Add (innerKey, new List<U> ());
856 innerKeys[innerKey].Add (element);
859 foreach (TOuter element in outer) {
860 TKey outerKey = outerKeySelector (element);
861 if (innerKeys.Contains (outerKey))
862 yield return resultSelector (element, innerKeys [outerKey]);
864 yield return resultSelector (element, Empty<TInner> ());
872 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
874 return Intersect (first, second, null);
877 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
879 if (first == null || second == null)
880 throw new ArgumentNullException ();
882 if (comparer == null)
883 comparer = EqualityComparer<TSource>.Default;
885 List<TSource> items = new List<TSource> (Distinct (first));
886 foreach (TSource element in second) {
887 if (Contains (items, element, comparer))
888 yield return element;
896 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
897 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
898 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
900 if (outer == null || inner == null || outerKeySelector == null ||
901 innerKeySelector == null || resultSelector == null)
902 throw new ArgumentNullException ();
904 if (comparer == null)
905 comparer = EqualityComparer<TKey>.Default;
907 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
908 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
909 foreach (U element in inner)
911 K innerKey = innerKeySelector (element);
912 if (!innerKeys.ContainsKey (innerKey))
913 innerKeys.Add (innerKey, new List<U> ());
914 innerKeys[innerKey].Add (element);
917 foreach (TOuter element in outer) {
918 TKey outerKey = outerKeySelector (element);
919 if (innerKeys.Contains (outerKey)) {
920 foreach (TInner innerElement in innerKeys [outerKey])
921 yield return resultSelector (element, innerElement);
926 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
927 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
928 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
930 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
936 public static TSource Last<TSource> (this IEnumerable<TSource> source)
939 throw new ArgumentNullException ();
941 bool noElements = true;
942 TSource lastElement = default (TSource);
943 foreach (TSource element in source) {
944 if (noElements) noElements = false;
945 lastElement = element;
951 throw new InvalidOperationException ();
954 public static TSource Last<TSource> (this IEnumerable<TSource> source,
955 Func<TSource, bool> predicate)
957 if (source == null || predicate == null)
958 throw new ArgumentNullException ();
960 bool noElements = true;
961 TSource lastElement = default (TSource);
962 foreach (TSource element in source) {
963 if (predicate (element)) {
964 if (noElements) noElements = false;
965 lastElement = element;
972 throw new InvalidOperationException ();
977 #region LastOrDefault
979 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
982 throw new ArgumentNullException ();
984 TSource lastElement = default (TSource);
985 foreach (TSource element in source)
986 lastElement = element;
991 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source,
992 Func<TSource, bool> predicate)
994 if (source == null || predicate == null)
995 throw new ArgumentNullException ();
997 TSource lastElement = default (TSource);
998 foreach (TSource element in source) {
999 if (predicate (element))
1000 lastElement = element;
1009 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1012 throw new ArgumentNullException ();
1015 foreach (TSource element in source)
1021 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1023 if (source == null || selector == null)
1024 throw new ArgumentNullException ();
1027 foreach (TSource element in source)
1028 if (selector (element))
1038 public static int Max (this IEnumerable<int> source)
1041 throw new ArgumentNullException ();
1043 int maximum = int.MinValue;
1045 foreach (int element in source) {
1046 if (element > maximum)
1052 throw new InvalidOperationException ();
1058 public static int? Max (this IEnumerable<int?> source)
1061 throw new ArgumentNullException ();
1063 bool onlyNull = true;
1064 int? maximum = int.MinValue;
1065 foreach (int? element in source) {
1066 if (element.HasValue) {
1068 if (element > maximum)
1072 return (onlyNull ? null : maximum);
1076 public static long Max (this IEnumerable<long> source)
1079 throw new ArgumentNullException ();
1081 long maximum = long.MinValue;
1083 foreach (long element in source) {
1084 if (element > maximum)
1090 throw new InvalidOperationException ();
1096 public static long? Max (this IEnumerable<long?> source)
1099 throw new ArgumentNullException ();
1101 bool onlyNull = true;
1102 long? maximum = long.MinValue;
1103 foreach (long? element in source) {
1104 if (element.HasValue) {
1106 if (element > maximum)
1110 return (onlyNull ? null : maximum);
1114 public static double Max (this IEnumerable<double> source)
1117 throw new ArgumentNullException ();
1119 double maximum = double.MinValue;
1121 foreach (double element in source) {
1122 if (element > maximum)
1128 throw new InvalidOperationException ();
1134 public static double? Max (this IEnumerable<double?> source)
1137 throw new ArgumentNullException ();
1139 bool onlyNull = true;
1140 double? maximum = double.MinValue;
1141 foreach (double? element in source) {
1142 if (element.HasValue) {
1144 if (element > maximum)
1148 return (onlyNull ? null : maximum);
1152 public static decimal Max (this IEnumerable<decimal> source)
1155 throw new ArgumentNullException ();
1157 decimal maximum = decimal.MinValue;
1159 foreach (decimal element in source) {
1160 if (element > maximum)
1166 throw new InvalidOperationException ();
1172 public static decimal? Max (this IEnumerable<decimal?> source)
1175 throw new ArgumentNullException ();
1177 bool onlyNull = true;
1178 decimal? maximum = decimal.MinValue;
1179 foreach (decimal? element in source) {
1180 if (element.HasValue) {
1182 if (element > maximum)
1186 return (onlyNull ? null : maximum);
1190 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1193 throw new ArgumentNullException ();
1195 bool notAssigned = true;
1196 TSource maximum = default (TSource);
1198 foreach (TSource element in source) {
1201 notAssigned = false;
1204 if (element is IComparable<TSource>)
1205 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1206 else if (element is System.IComparable)
1207 comparison = ((System.IComparable) element).CompareTo (maximum);
1209 throw new ArgumentNullException ();
1218 throw new InvalidOperationException ();
1224 public static int Max<TSource> (this IEnumerable<TSource> source,
1225 Func<TSource, int> selector)
1227 if (source == null || selector == null)
1228 throw new ArgumentNullException ();
1230 int maximum = int.MinValue;
1232 foreach (TSource item in source) {
1233 int element = selector (item);
1234 if (element > maximum)
1240 throw new InvalidOperationException ();
1246 public static int? Max<TSource> (this IEnumerable<TSource> source,
1247 Func<TSource, int?> selector)
1249 if (source == null || selector == null)
1250 throw new ArgumentNullException ();
1252 bool onlyNull = true;
1253 int? maximum = int.MinValue;
1254 foreach (TSource item in source) {
1255 int? element = selector (item);
1256 if (element.HasValue) {
1258 if (element > maximum)
1262 return (onlyNull ? null : maximum);
1266 public static long Max<TSource> (this IEnumerable<TSource> source,
1267 Func<TSource, long> selector)
1269 if (source == null || selector == null)
1270 throw new ArgumentNullException ();
1272 long maximum = long.MinValue;
1274 foreach (TSource item in source) {
1275 long element = selector (item);
1276 if (element > maximum)
1282 throw new InvalidOperationException ();
1288 public static long? Max<TSource> (this IEnumerable<TSource> source,
1289 Func<TSource, long?> selector)
1291 if (source == null || selector == null)
1292 throw new ArgumentNullException ();
1294 bool onlyNull = true;
1295 long? maximum = long.MinValue;
1296 foreach (TSource item in source) {
1297 long? element = selector (item);
1298 if (element.HasValue) {
1300 if (element > maximum)
1304 return (onlyNull ? null : maximum);
1308 public static double Max<TSource> (this IEnumerable<TSource> source,
1309 Func<TSource, double> selector)
1311 if (source == null || selector == null)
1312 throw new ArgumentNullException ();
1314 double maximum = double.MinValue;
1316 foreach (TSource item in source) {
1317 double element = selector (item);
1318 if (element > maximum)
1324 throw new InvalidOperationException ();
1330 public static double? Max<TSource> (this IEnumerable<TSource> source,
1331 Func<TSource, double?> selector)
1333 if (source == null || selector == null)
1334 throw new ArgumentNullException ();
1336 bool onlyNull = true;
1337 double? maximum = double.MinValue;
1338 foreach (TSource item in source) {
1339 double? element = selector (item);
1340 if (element.HasValue) {
1342 if (element > maximum)
1346 return (onlyNull ? null : maximum);
1350 public static decimal Max<TSource> (this IEnumerable<TSource> source,
1351 Func<TSource, decimal> selector)
1353 if (source == null || selector == null)
1354 throw new ArgumentNullException ();
1356 decimal maximum = decimal.MinValue;
1358 foreach (TSource item in source) {
1359 decimal element = selector (item);
1360 if (element > maximum)
1366 throw new InvalidOperationException ();
1372 public static decimal? Max<TSource> (this IEnumerable<TSource> source,
1373 Func<TSource, decimal?> selector)
1375 if (source == null || selector == null)
1376 throw new ArgumentNullException ();
1378 bool onlyNull = true;
1379 decimal? maximum = decimal.MinValue;
1380 foreach (TSource item in source) {
1381 decimal? element = selector (item);
1382 if (element.HasValue) {
1384 if (element > maximum)
1388 return (onlyNull ? null : maximum);
1392 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source,
1393 Func<TSource, TResult> selector)
1395 if (source == null || selector == null)
1396 throw new ArgumentNullException ();
1398 bool notAssigned = true;
1399 TResult maximum = default (TResult);
1401 foreach (TSource item in source) {
1402 TResult element = selector (item);
1405 notAssigned = false;
1408 if (element is IComparable<TResult>)
1409 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1410 else if (element is System.IComparable)
1411 comparison = ((System.IComparable) element).CompareTo (maximum);
1413 throw new ArgumentNullException ();
1422 throw new InvalidOperationException ();
1431 public static int Min (this IEnumerable<int> source)
1434 throw new ArgumentNullException ();
1436 int minimum = int.MaxValue;
1438 foreach (int element in source) {
1439 if (element < minimum)
1445 throw new InvalidOperationException ();
1451 public static int? Min (this IEnumerable<int?> source)
1454 throw new ArgumentNullException ();
1456 bool onlyNull = true;
1457 int? minimum = int.MaxValue;
1458 foreach (int? element in source) {
1459 if (element.HasValue) {
1461 if (element < minimum)
1465 return (onlyNull ? null : minimum);
1468 public static long Min (this IEnumerable<long> source)
1471 throw new ArgumentNullException ();
1473 long minimum = long.MaxValue;
1475 foreach (long element in source) {
1476 if (element < minimum)
1482 throw new InvalidOperationException ();
1488 public static long? Min (this IEnumerable<long?> source)
1491 throw new ArgumentNullException ();
1493 bool onlyNull = true;
1494 long? minimum = long.MaxValue;
1495 foreach (long? element in source) {
1496 if (element.HasValue) {
1498 if (element < minimum)
1502 return (onlyNull ? null : minimum);
1506 public static double Min (this IEnumerable<double> source)
1509 throw new ArgumentNullException ();
1511 double minimum = double.MaxValue;
1513 foreach (double element in source) {
1514 if (element < minimum)
1520 throw new InvalidOperationException ();
1526 public static double? Min (this IEnumerable<double?> source)
1529 throw new ArgumentNullException ();
1531 bool onlyNull = true;
1532 double? minimum = double.MaxValue;
1533 foreach (double? element in source) {
1534 if (element.HasValue) {
1536 if (element < minimum)
1540 return (onlyNull ? null : minimum);
1544 public static decimal Min (this IEnumerable<decimal> source)
1547 throw new ArgumentNullException ();
1549 decimal minimum = decimal.MaxValue;
1551 foreach (decimal element in source) {
1552 if (element < minimum)
1558 throw new InvalidOperationException ();
1564 public static decimal? Min (this IEnumerable<decimal?> source)
1567 throw new ArgumentNullException ();
1569 bool onlyNull = true;
1570 decimal? minimum = decimal.MaxValue;
1571 foreach (decimal? element in source) {
1572 if (element.HasValue) {
1574 if (element < minimum)
1578 return (onlyNull ? null : minimum);
1582 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1585 throw new ArgumentNullException ();
1587 bool notAssigned = true;
1588 TSource minimum = default (TSource);
1590 foreach (TSource element in source) {
1593 notAssigned = false;
1596 if (element is IComparable<TSource>)
1597 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1598 else if (element is System.IComparable)
1599 comparison = ((System.IComparable) element).CompareTo (minimum);
1601 throw new ArgumentNullException ();
1610 throw new InvalidOperationException ();
1616 public static int Min<TSource> (this IEnumerable<TSource> source,
1617 Func<TSource, int> selector)
1619 if (source == null || selector == null)
1620 throw new ArgumentNullException ();
1622 int minimum = int.MaxValue;
1624 foreach (TSource item in source) {
1625 int element = selector (item);
1626 if (element < minimum)
1632 throw new InvalidOperationException ();
1638 public static int? Min<TSource> (this IEnumerable<TSource> source,
1639 Func<TSource, int?> selector)
1641 if (source == null || selector == null)
1642 throw new ArgumentNullException ();
1644 bool onlyNull = true;
1645 int? minimum = int.MaxValue;
1646 foreach (TSource item in source) {
1647 int? element = selector (item);
1648 if (element.HasValue) {
1650 if (element < minimum)
1654 return (onlyNull ? null : minimum);
1658 public static long Min<TSource> (this IEnumerable<TSource> source,
1659 Func<TSource, long> selector)
1661 if (source == null || selector == null)
1662 throw new ArgumentNullException ();
1664 long minimum = long.MaxValue;
1666 foreach (TSource item in source) {
1667 long element = selector (item);
1668 if (element < minimum)
1674 throw new InvalidOperationException ();
1680 public static long? Min<TSource> (this IEnumerable<TSource> source,
1681 Func<TSource, long?> selector)
1683 if (source == null || selector == null)
1684 throw new ArgumentNullException ();
1686 bool onlyNull = true;
1687 long? minimum = long.MaxValue;
1688 foreach (TSource item in source) {
1689 long? element = selector (item);
1690 if (element.HasValue) {
1692 if (element < minimum)
1696 return (onlyNull ? null : minimum);
1700 public static double Min<TSource> (this IEnumerable<TSource> source,
1701 Func<TSource, double> selector)
1703 if (source == null || selector == null)
1704 throw new ArgumentNullException ();
1706 double minimum = double.MaxValue;
1708 foreach (TSource item in source) {
1709 double element = selector (item);
1710 if (element < minimum)
1716 throw new InvalidOperationException ();
1722 public static double? Min<TSource> (this IEnumerable<TSource> source,
1723 Func<TSource, double?> selector)
1725 if (source == null || selector == null)
1726 throw new ArgumentNullException ();
1728 bool onlyNull = true;
1729 double? minimum = double.MaxValue;
1730 foreach (TSource item in source) {
1731 double? element = selector (item);
1732 if (element.HasValue) {
1734 if (element < minimum)
1738 return (onlyNull ? null : minimum);
1742 public static decimal Min<TSource> (this IEnumerable<TSource> source,
1743 Func<TSource, decimal> selector)
1745 if (source == null || selector == null)
1746 throw new ArgumentNullException ();
1748 decimal minimum = decimal.MaxValue;
1750 foreach (TSource item in source) {
1751 decimal element = selector (item);
1752 if (element < minimum)
1758 throw new InvalidOperationException ();
1764 public static decimal? Min<TSource> (this IEnumerable<TSource> source,
1765 Func<TSource, decimal?> selector)
1767 if (source == null || selector == null)
1768 throw new ArgumentNullException ();
1770 bool onlyNull = true;
1771 decimal? minimum = decimal.MaxValue;
1772 foreach (TSource item in source) {
1773 decimal? element = selector (item);
1774 if (element.HasValue) {
1776 if (element < minimum)
1780 return (onlyNull ? null : minimum);
1784 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source,
1785 Func<TSource, TResult> selector)
1787 if (source == null || selector == null)
1788 throw new ArgumentNullException ();
1790 bool notAssigned = true;
1791 TResult minimum = default (TResult);
1793 foreach (TSource item in source) {
1794 TResult element = selector (item);
1797 notAssigned = false;
1800 if (element is IComparable<TResult>)
1801 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1802 else if (element is System.IComparable)
1803 comparison = ((System.IComparable) element).CompareTo (minimum);
1805 throw new ArgumentNullException ();
1814 throw new InvalidOperationException ();
1823 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1826 throw new ArgumentNullException ();
1828 foreach (object element in source)
1829 if (element is TResult)
1830 yield return (TResult) element;
1837 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1838 Func<TSource, TKey> keySelector)
1840 return OrderBy<TSource, TKey> (source, keySelector, null);
1844 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1845 Func<TSource, TKey> keySelector,
1846 IComparer<TKey> comparer)
1848 if (source == null || keySelector == null)
1849 throw new ArgumentNullException ();
1851 return new InternalOrderedSequence<TSource, TKey> (
1852 source, keySelector, comparer, false);
1857 #region OrderByDescending
1859 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1860 Func<TSource, TKey> keySelector)
1862 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1866 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1867 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1869 if (source == null || keySelector == null)
1870 throw new ArgumentNullException ();
1872 return new InternalOrderedSequence<TSource, TKey> (
1873 source, keySelector, comparer, true);
1880 public static IEnumerable<int> Range (int start, int count)
1882 if (count < 0 || (start + count - 1) > int.MaxValue)
1883 throw new ArgumentOutOfRangeException ();
1885 for (int i = start; i < (start + count - 1); i++)
1893 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1896 throw new ArgumentOutOfRangeException ();
1898 for (int i = 0; i < count; i++)
1899 yield return element;
1907 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1910 throw new ArgumentNullException ();
1912 List<TSource> list = new List<TSource> (source);
1921 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1922 Func<TSource, TResult> selector)
1924 if (source == null || selector == null)
1925 throw new ArgumentNullException ();
1927 foreach (TSource element in source)
1928 yield return selector (element);
1932 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1933 Func<TSource, int, TResult> selector)
1935 if (source == null || selector == null)
1936 throw new ArgumentNullException ();
1939 foreach (TSource element in source) {
1940 yield return selector (element, counter);
1949 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1950 Func<TSource, IEnumerable<TResult>> selector)
1952 if (source == null || selector == null)
1953 throw new ArgumentNullException ();
1955 foreach (TSource element in source)
1956 foreach (TResult item in selector (element))
1961 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1962 Func<TSource, int, IEnumerable<TResult>> selector)
1964 if (source == null || selector == null)
1965 throw new ArgumentNullException ();
1968 foreach (TSource element in source) {
1969 foreach (TResult item in selector (element, counter++))
1975 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1976 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1978 if (source == null || collectionSelector == null || selector == null)
1979 throw new ArgumentNullException ();
1981 foreach (TSource element in source)
1982 foreach (TCollection collection in collectionSelector (element))
1983 yield return selector (element, collection);
1986 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1987 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1989 if (source == null || collectionSelector == null || selector == null)
1990 throw new ArgumentNullException ();
1993 foreach (TSource element in source)
1994 foreach (TCollection collection in collectionSelector (element, counter++))
1995 yield return selector (element, collection);
2002 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2005 throw new ArgumentNullException ();
2007 bool otherElement = false;
2008 TSource singleElement = default (TSource);
2009 foreach (TSource element in source) {
2010 if (otherElement) throw new InvalidOperationException ();
2011 if (!otherElement) otherElement = true;
2012 singleElement = element;
2016 return singleElement;
2018 throw new InvalidOperationException ();
2022 public static TSource Single<TSource> (this IEnumerable<TSource> source,
2023 Func<TSource, bool> predicate)
2025 if (source == null || predicate == null)
2026 throw new ArgumentNullException ();
2028 bool otherElement = false;
2029 TSource singleElement = default (TSource);
2030 foreach (TSource element in source) {
2031 if (predicate (element)) {
2032 if (otherElement) throw new InvalidOperationException ();
2033 if (!otherElement) otherElement = true;
2034 singleElement = element;
2039 return singleElement;
2041 throw new InvalidOperationException ();
2046 #region SingleOrDefault
2048 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2051 throw new ArgumentNullException ();
2053 bool otherElement = false;
2054 TSource singleElement = default (TSource);
2055 foreach (TSource element in source) {
2056 if (otherElement) throw new InvalidOperationException ();
2057 if (!otherElement) otherElement = true;
2058 singleElement = element;
2061 return singleElement;
2065 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source,
2066 Func<TSource, bool> predicate)
2068 if (source == null || predicate == null)
2069 throw new ArgumentNullException ();
2071 bool otherElement = false;
2072 TSource singleElement = default (TSource);
2073 foreach (TSource element in source) {
2074 if (predicate (element)) {
2075 if (otherElement) throw new InvalidOperationException ();
2076 if (!otherElement) otherElement = true;
2077 singleElement = element;
2081 return singleElement;
2087 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2090 throw new NotSupportedException ();
2093 foreach (TSource e in source) {
2104 public static IEnumerable<TSource> SkipWhile<TSource> (
2105 this IEnumerable<TSource> source,
2106 Func<TSource, bool> predicate)
2108 if (source == null || predicate == null)
2109 throw new ArgumentNullException ();
2113 foreach (TSource element in source) {
2115 yield return element;
2117 if (!predicate (element)) {
2118 yield return element;
2125 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source,
2126 Func<TSource, int, bool> predicate)
2128 if (source == null || predicate == null)
2129 throw new ArgumentNullException ();
2134 foreach (TSource element in source) {
2136 yield return element;
2138 if (!predicate (element, counter)) {
2139 yield return element;
2150 public static int Sum (this IEnumerable<int> source)
2153 throw new ArgumentNullException ("source");
2156 foreach (int element in source)
2163 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2165 if (source == null || selector == null)
2166 throw new ArgumentNullException ();
2169 foreach (TSource element in source)
2170 sum += selector (element);
2176 public static int? Sum (this IEnumerable<int?> source)
2179 throw new ArgumentNullException ();
2182 foreach (int? element in source)
2183 if (element.HasValue)
2184 sum += element.Value;
2190 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2192 if (source == null || selector == null)
2193 throw new ArgumentNullException ();
2196 foreach (TSource element in source) {
2197 int? item = selector (element);
2206 public static long Sum (this IEnumerable<long> source)
2209 throw new ArgumentNullException ();
2212 foreach (long element in source)
2219 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2221 if (source == null || selector == null)
2222 throw new ArgumentNullException ();
2225 foreach (TSource element in source)
2226 sum += selector (element);
2232 public static long? Sum (this IEnumerable<long?> source)
2235 throw new ArgumentNullException ();
2238 foreach (long? element in source)
2239 if (element.HasValue)
2240 sum += element.Value;
2246 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2248 if (source == null || selector == null)
2249 throw new ArgumentNullException ();
2252 foreach (TSource element in source) {
2253 long? item = selector (element);
2262 public static double Sum (this IEnumerable<double> source)
2265 throw new ArgumentNullException ();
2268 foreach (double element in source)
2275 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2277 if (source == null || selector == null)
2278 throw new ArgumentNullException ();
2281 foreach (TSource element in source)
2282 sum += selector (element);
2288 public static double? Sum (this IEnumerable<double?> source)
2291 throw new ArgumentNullException ();
2294 foreach (double? element in source)
2295 if (element.HasValue)
2296 sum += element.Value;
2302 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2304 if (source == null || selector == null)
2305 throw new ArgumentNullException ();
2308 foreach (TSource element in source) {
2309 double? item = selector (element);
2318 public static decimal Sum (this IEnumerable<decimal> source)
2321 throw new ArgumentNullException ();
2324 foreach (decimal element in source)
2331 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2333 if (source == null || selector == null)
2334 throw new ArgumentNullException ();
2337 foreach (TSource element in source)
2338 sum += selector (element);
2344 public static decimal? Sum (this IEnumerable<decimal?> source)
2347 throw new ArgumentNullException ();
2350 foreach (decimal? element in source)
2351 if (element.HasValue)
2352 sum += element.Value;
2358 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2360 if (source == null || selector == null)
2361 throw new ArgumentNullException ();
2364 foreach (TSource element in source) {
2365 decimal? item = selector (element);
2376 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2379 throw new ArgumentNullException ();
2385 foreach (TSource element in source) {
2386 yield return element;
2388 if (counter == count)
2398 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2400 if (source == null || predicate == null)
2401 throw new ArgumentNullException ();
2403 foreach (TSource element in source) {
2404 if (predicate (element))
2405 yield return element;
2411 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2413 if (source == null || predicate == null)
2414 throw new ArgumentNullException ();
2417 foreach (TSource element in source) {
2418 if (predicate (element, counter))
2419 yield return element;
2430 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2432 return ThenBy<TSource, TKey> (source, keySelector, null);
2436 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2437 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2439 if (source == null || keySelector == null)
2440 throw new ArgumentNullException ();
2442 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2447 #region ThenByDescending
2449 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2450 Func<TSource, TKey> keySelector)
2452 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2456 public static IOrderedEnumerable<TSource> ThenByDescending<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, true);
2468 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2471 throw new ArgumentNullException ();
2473 List<TSource> list = new List<TSource> (source);
2474 return list.ToArray ();
2479 #region ToDictionary
2480 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2482 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2486 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2489 throw new ArgumentNullException ("source");
2490 if (keySelector == null)
2491 throw new ArgumentNullException ("keySelector");
2492 if (elementSelector == null)
2493 throw new ArgumentNullException ("elementSelector");
2495 Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement> (comparer);
2496 foreach (TSource e in source) {
2497 dict.Add (keySelector (e), elementSelector (e));
2505 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2508 throw new ArgumentNullException ("source");
2510 return new List<TSource> (source);
2516 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2518 return ToLookup<TSource, TKey> (source, keySelector, null);
2522 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2523 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2525 if (source == null || keySelector == null)
2526 throw new ArgumentNullException ();
2528 Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2529 foreach (TSource element in source) {
2530 TKey key = keySelector (element);
2532 throw new ArgumentNullException ();
2533 if (!dictionary.ContainsKey (key))
2534 dictionary.Add (key, new List<TSource> ());
2535 dictionary [key].Add (element);
2537 return new Lookup<TKey, TSource> (dictionary);
2541 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2542 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2544 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2548 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2549 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2551 if (source == null || keySelector == null || elementSelector == null)
2552 throw new ArgumentNullException ();
2554 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2555 foreach (TSource element in source) {
2556 TKey key = keySelector (element);
2558 throw new ArgumentNullException ();
2559 if (!dictionary.ContainsKey (key))
2560 dictionary.Add (key, new List<TElement> ());
2561 dictionary [key].Add (elementSelector (element));
2563 return new Lookup<TKey, TElement> (dictionary);
2570 public static IEnumerable<T> ToSequence<T> (this IEnumerable<T> source)
2572 return (IEnumerable<T>) source;
2580 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2582 if (first == null || second == null)
2583 throw new ArgumentNullException ();
2585 List<TSource> items = new List<TSource> ();
2586 foreach (TSource element in first) {
2587 if (IndexOf (items, element) == -1) {
2588 items.Add (element);
2589 yield return element;
2592 foreach (TSource element in second) {
2593 if (IndexOf (items, element) == -1) {
2594 items.Add (element);
2595 yield return element;
2604 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2605 Func<TSource, bool> predicate)
2607 if (source == null || predicate == null)
2608 throw new ArgumentNullException ();
2610 foreach (TSource element in source)
2611 if (predicate (element))
2612 yield return element;
2616 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2617 Func<TSource, int, bool> predicate)
2619 if (source == null || predicate == null)
2620 throw new ArgumentNullException ();
2623 foreach (TSource element in source) {
2624 if (predicate (element, counter))
2625 yield return element;
2632 // These methods are not included in the
2633 // .NET Standard Query Operators Specification,
2634 // but they provide additional useful commands
2638 private static bool Equals<T> (T first, T second)
2640 // Mostly, values in Enumerable<T>
2641 // sequences need to be compared using
2642 // Equals and GetHashCode
2644 if (first == null || second == null)
2645 return (first == null && second == null);
2647 return ((first.Equals (second) ||
2648 first.GetHashCode () == second.GetHashCode ()));
2655 static int IndexOf<T> (this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2657 if (comparer == null)
2658 comparer = EqualityComparer<T>.Default;
2661 foreach (T element in source) {
2662 if (comparer.Equals (element, item))
2666 // The item was not found
2670 static int IndexOf<T> (this IEnumerable<T> source, T item)
2672 return IndexOf<T> (source, item, null);
2676 #region ToReadOnlyCollection
2677 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (IEnumerable<TSource> source)
2680 return new ReadOnlyCollection<TSource> (new List<TSource> ());
2682 if (typeof (ReadOnlyCollection<TSource>).IsInstanceOfType (source))
2683 return source as ReadOnlyCollection<TSource>;
2685 return new ReadOnlyCollection<TSource> (ToArray<TSource> (source));