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 (first));
649 foreach (TSource element in second) {
650 int index = IndexOf (items, element, comparer);
654 items.RemoveAt (index);
656 foreach (TSource item in items)
664 public static TSource First<TSource> (this IEnumerable<TSource> source)
667 throw new ArgumentNullException ();
669 foreach (TSource element in source)
672 throw new InvalidOperationException ();
676 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
678 if (source == null || predicate == null)
679 throw new ArgumentNullException ();
681 foreach (TSource element in source) {
682 if (predicate (element))
686 throw new InvalidOperationException ();
691 #region FirstOrDefault
693 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
696 throw new ArgumentNullException ();
698 foreach (TSource element in source)
701 return default (TSource);
705 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
707 if (source == null || predicate == null)
708 throw new ArgumentNullException ();
710 foreach (TSource element in source) {
711 if (predicate (element))
715 return default (TSource);
722 private static List<T> ContainsGroup<K, T> (
723 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
725 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
726 foreach (KeyValuePair<K, List<T>> value in items) {
727 if (comparerInUse.Equals (value.Key, key))
734 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
735 Func<TSource, TKey> keySelector)
737 return GroupBy<TSource, TKey> (source, keySelector, null);
741 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
742 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
744 if (source == null || keySelector == null)
745 throw new ArgumentNullException ();
747 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
748 List<TSource> nullList = new List<TSource> ();
750 int nullCounter = -1;
752 foreach (TSource element in source) {
753 TKey key = keySelector (element);
755 nullList.Add (element);
756 if (nullCounter == -1) {
757 nullCounter = counter;
761 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
763 group = new List<TSource> ();
764 groups.Add (key, group);
772 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
773 if (counter == nullCounter) {
774 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
775 yield return nullGroup;
778 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
779 yield return grouping;
785 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
786 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
788 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
792 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
793 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
795 if (source == null || keySelector == null || elementSelector == null)
796 throw new ArgumentNullException ();
798 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
799 List<TElement> nullList = new List<TElement> ();
801 int nullCounter = -1;
803 foreach (TSource item in source) {
804 TKey key = keySelector (item);
805 TElement element = elementSelector (item);
807 nullList.Add (element);
808 if (nullCounter == -1) {
809 nullCounter = counter;
813 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
815 group = new List<TElement> ();
816 groups.Add (key, group);
824 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
825 if (counter == nullCounter) {
826 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
827 yield return nullGroup;
830 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
831 yield return grouping;
840 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
841 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
842 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
844 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
847 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
848 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
849 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
850 IEqualityComparer<TKey> comparer)
852 if (outer == null || inner == null || outerKeySelector == null ||
853 innerKeySelector == null || resultSelector == null)
854 throw new ArgumentNullException ();
856 if (comparer == null)
857 comparer = EqualityComparer<TKey>.Default;
859 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
860 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
861 foreach (U element in inner)
863 K innerKey = innerKeySelector (element);
864 if (!innerKeys.ContainsKey (innerKey))
865 innerKeys.Add (innerKey, new List<U> ());
866 innerKeys[innerKey].Add (element);
869 foreach (TOuter element in outer) {
870 TKey outerKey = outerKeySelector (element);
871 if (innerKeys.Contains (outerKey))
872 yield return resultSelector (element, innerKeys [outerKey]);
874 yield return resultSelector (element, Empty<TInner> ());
883 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
885 if (first == null || second == null)
886 throw new ArgumentNullException ();
888 List<TSource> items = new List<TSource> (Distinct (first));
889 bool [] marked = new bool [items.Count];
890 for (int i = 0; i < marked.Length; i++)
893 foreach (TSource element in second) {
894 int index = IndexOf (items, element);
896 marked [index] = true;
898 for (int i = 0; i < marked.Length; i++) {
900 yield return items [i];
908 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
909 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
910 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
912 if (outer == null || inner == null || outerKeySelector == null ||
913 innerKeySelector == null || resultSelector == null)
914 throw new ArgumentNullException ();
916 if (comparer == null)
917 comparer = EqualityComparer<TKey>.Default;
919 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
920 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
921 foreach (U element in inner)
923 K innerKey = innerKeySelector (element);
924 if (!innerKeys.ContainsKey (innerKey))
925 innerKeys.Add (innerKey, new List<U> ());
926 innerKeys[innerKey].Add (element);
929 foreach (TOuter element in outer) {
930 TKey outerKey = outerKeySelector (element);
931 if (innerKeys.Contains (outerKey)) {
932 foreach (TInner innerElement in innerKeys [outerKey])
933 yield return resultSelector (element, innerElement);
938 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
939 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
940 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
942 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
948 public static TSource Last<TSource> (this IEnumerable<TSource> source)
951 throw new ArgumentNullException ();
953 bool noElements = true;
954 TSource lastElement = default (TSource);
955 foreach (TSource element in source) {
956 if (noElements) noElements = false;
957 lastElement = element;
963 throw new InvalidOperationException ();
966 public static TSource Last<TSource> (this IEnumerable<TSource> source,
967 Func<TSource, bool> predicate)
969 if (source == null || predicate == null)
970 throw new ArgumentNullException ();
972 bool noElements = true;
973 TSource lastElement = default (TSource);
974 foreach (TSource element in source) {
975 if (predicate (element)) {
976 if (noElements) noElements = false;
977 lastElement = element;
984 throw new InvalidOperationException ();
989 #region LastOrDefault
991 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
994 throw new ArgumentNullException ();
996 TSource lastElement = default (TSource);
997 foreach (TSource element in source)
998 lastElement = element;
1003 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source,
1004 Func<TSource, bool> predicate)
1006 if (source == null || predicate == null)
1007 throw new ArgumentNullException ();
1009 TSource lastElement = default (TSource);
1010 foreach (TSource element in source) {
1011 if (predicate (element))
1012 lastElement = element;
1021 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1024 throw new ArgumentNullException ();
1027 foreach (TSource element in source)
1033 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1035 if (source == null || selector == null)
1036 throw new ArgumentNullException ();
1039 foreach (TSource element in source)
1040 if (selector (element))
1050 public static int Max (this IEnumerable<int> source)
1053 throw new ArgumentNullException ();
1055 int maximum = int.MinValue;
1057 foreach (int element in source) {
1058 if (element > maximum)
1064 throw new InvalidOperationException ();
1070 public static int? Max (this IEnumerable<int?> source)
1073 throw new ArgumentNullException ();
1075 bool onlyNull = true;
1076 int? maximum = int.MinValue;
1077 foreach (int? element in source) {
1078 if (element.HasValue) {
1080 if (element > maximum)
1084 return (onlyNull ? null : maximum);
1088 public static long Max (this IEnumerable<long> source)
1091 throw new ArgumentNullException ();
1093 long maximum = long.MinValue;
1095 foreach (long element in source) {
1096 if (element > maximum)
1102 throw new InvalidOperationException ();
1108 public static long? Max (this IEnumerable<long?> source)
1111 throw new ArgumentNullException ();
1113 bool onlyNull = true;
1114 long? maximum = long.MinValue;
1115 foreach (long? element in source) {
1116 if (element.HasValue) {
1118 if (element > maximum)
1122 return (onlyNull ? null : maximum);
1126 public static double Max (this IEnumerable<double> source)
1129 throw new ArgumentNullException ();
1131 double maximum = double.MinValue;
1133 foreach (double element in source) {
1134 if (element > maximum)
1140 throw new InvalidOperationException ();
1146 public static double? Max (this IEnumerable<double?> source)
1149 throw new ArgumentNullException ();
1151 bool onlyNull = true;
1152 double? maximum = double.MinValue;
1153 foreach (double? element in source) {
1154 if (element.HasValue) {
1156 if (element > maximum)
1160 return (onlyNull ? null : maximum);
1164 public static decimal Max (this IEnumerable<decimal> source)
1167 throw new ArgumentNullException ();
1169 decimal maximum = decimal.MinValue;
1171 foreach (decimal element in source) {
1172 if (element > maximum)
1178 throw new InvalidOperationException ();
1184 public static decimal? Max (this IEnumerable<decimal?> source)
1187 throw new ArgumentNullException ();
1189 bool onlyNull = true;
1190 decimal? maximum = decimal.MinValue;
1191 foreach (decimal? element in source) {
1192 if (element.HasValue) {
1194 if (element > maximum)
1198 return (onlyNull ? null : maximum);
1202 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1205 throw new ArgumentNullException ();
1207 bool notAssigned = true;
1208 TSource maximum = default (TSource);
1210 foreach (TSource element in source) {
1213 notAssigned = false;
1216 if (element is IComparable<TSource>)
1217 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1218 else if (element is System.IComparable)
1219 comparison = ((System.IComparable) element).CompareTo (maximum);
1221 throw new ArgumentNullException ();
1230 throw new InvalidOperationException ();
1236 public static int Max<TSource> (this IEnumerable<TSource> source,
1237 Func<TSource, int> selector)
1239 if (source == null || selector == null)
1240 throw new ArgumentNullException ();
1242 int maximum = int.MinValue;
1244 foreach (TSource item in source) {
1245 int element = selector (item);
1246 if (element > maximum)
1252 throw new InvalidOperationException ();
1258 public static int? Max<TSource> (this IEnumerable<TSource> source,
1259 Func<TSource, int?> selector)
1261 if (source == null || selector == null)
1262 throw new ArgumentNullException ();
1264 bool onlyNull = true;
1265 int? maximum = int.MinValue;
1266 foreach (TSource item in source) {
1267 int? element = selector (item);
1268 if (element.HasValue) {
1270 if (element > maximum)
1274 return (onlyNull ? null : maximum);
1278 public static long Max<TSource> (this IEnumerable<TSource> source,
1279 Func<TSource, long> selector)
1281 if (source == null || selector == null)
1282 throw new ArgumentNullException ();
1284 long maximum = long.MinValue;
1286 foreach (TSource item in source) {
1287 long element = selector (item);
1288 if (element > maximum)
1294 throw new InvalidOperationException ();
1300 public static long? Max<TSource> (this IEnumerable<TSource> source,
1301 Func<TSource, long?> selector)
1303 if (source == null || selector == null)
1304 throw new ArgumentNullException ();
1306 bool onlyNull = true;
1307 long? maximum = long.MinValue;
1308 foreach (TSource item in source) {
1309 long? element = selector (item);
1310 if (element.HasValue) {
1312 if (element > maximum)
1316 return (onlyNull ? null : maximum);
1320 public static double Max<TSource> (this IEnumerable<TSource> source,
1321 Func<TSource, double> selector)
1323 if (source == null || selector == null)
1324 throw new ArgumentNullException ();
1326 double maximum = double.MinValue;
1328 foreach (TSource item in source) {
1329 double element = selector (item);
1330 if (element > maximum)
1336 throw new InvalidOperationException ();
1342 public static double? Max<TSource> (this IEnumerable<TSource> source,
1343 Func<TSource, double?> selector)
1345 if (source == null || selector == null)
1346 throw new ArgumentNullException ();
1348 bool onlyNull = true;
1349 double? maximum = double.MinValue;
1350 foreach (TSource item in source) {
1351 double? element = selector (item);
1352 if (element.HasValue) {
1354 if (element > maximum)
1358 return (onlyNull ? null : maximum);
1362 public static decimal Max<TSource> (this IEnumerable<TSource> source,
1363 Func<TSource, decimal> selector)
1365 if (source == null || selector == null)
1366 throw new ArgumentNullException ();
1368 decimal maximum = decimal.MinValue;
1370 foreach (TSource item in source) {
1371 decimal element = selector (item);
1372 if (element > maximum)
1378 throw new InvalidOperationException ();
1384 public static decimal? Max<TSource> (this IEnumerable<TSource> source,
1385 Func<TSource, decimal?> selector)
1387 if (source == null || selector == null)
1388 throw new ArgumentNullException ();
1390 bool onlyNull = true;
1391 decimal? maximum = decimal.MinValue;
1392 foreach (TSource item in source) {
1393 decimal? element = selector (item);
1394 if (element.HasValue) {
1396 if (element > maximum)
1400 return (onlyNull ? null : maximum);
1404 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source,
1405 Func<TSource, TResult> selector)
1407 if (source == null || selector == null)
1408 throw new ArgumentNullException ();
1410 bool notAssigned = true;
1411 TResult maximum = default (TResult);
1413 foreach (TSource item in source) {
1414 TResult element = selector (item);
1417 notAssigned = false;
1420 if (element is IComparable<TResult>)
1421 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1422 else if (element is System.IComparable)
1423 comparison = ((System.IComparable) element).CompareTo (maximum);
1425 throw new ArgumentNullException ();
1434 throw new InvalidOperationException ();
1443 public static int Min (this IEnumerable<int> source)
1446 throw new ArgumentNullException ();
1448 int minimum = int.MaxValue;
1450 foreach (int element in source) {
1451 if (element < minimum)
1457 throw new InvalidOperationException ();
1463 public static int? Min (this IEnumerable<int?> source)
1466 throw new ArgumentNullException ();
1468 bool onlyNull = true;
1469 int? minimum = int.MaxValue;
1470 foreach (int? element in source) {
1471 if (element.HasValue) {
1473 if (element < minimum)
1477 return (onlyNull ? null : minimum);
1480 public static long Min (this IEnumerable<long> source)
1483 throw new ArgumentNullException ();
1485 long minimum = long.MaxValue;
1487 foreach (long element in source) {
1488 if (element < minimum)
1494 throw new InvalidOperationException ();
1500 public static long? Min (this IEnumerable<long?> source)
1503 throw new ArgumentNullException ();
1505 bool onlyNull = true;
1506 long? minimum = long.MaxValue;
1507 foreach (long? element in source) {
1508 if (element.HasValue) {
1510 if (element < minimum)
1514 return (onlyNull ? null : minimum);
1518 public static double Min (this IEnumerable<double> source)
1521 throw new ArgumentNullException ();
1523 double minimum = double.MaxValue;
1525 foreach (double element in source) {
1526 if (element < minimum)
1532 throw new InvalidOperationException ();
1538 public static double? Min (this IEnumerable<double?> source)
1541 throw new ArgumentNullException ();
1543 bool onlyNull = true;
1544 double? minimum = double.MaxValue;
1545 foreach (double? element in source) {
1546 if (element.HasValue) {
1548 if (element < minimum)
1552 return (onlyNull ? null : minimum);
1556 public static decimal Min (this IEnumerable<decimal> source)
1559 throw new ArgumentNullException ();
1561 decimal minimum = decimal.MaxValue;
1563 foreach (decimal element in source) {
1564 if (element < minimum)
1570 throw new InvalidOperationException ();
1576 public static decimal? Min (this IEnumerable<decimal?> source)
1579 throw new ArgumentNullException ();
1581 bool onlyNull = true;
1582 decimal? minimum = decimal.MaxValue;
1583 foreach (decimal? element in source) {
1584 if (element.HasValue) {
1586 if (element < minimum)
1590 return (onlyNull ? null : minimum);
1594 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1597 throw new ArgumentNullException ();
1599 bool notAssigned = true;
1600 TSource minimum = default (TSource);
1602 foreach (TSource element in source) {
1605 notAssigned = false;
1608 if (element is IComparable<TSource>)
1609 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1610 else if (element is System.IComparable)
1611 comparison = ((System.IComparable) element).CompareTo (minimum);
1613 throw new ArgumentNullException ();
1622 throw new InvalidOperationException ();
1628 public static int Min<TSource> (this IEnumerable<TSource> source,
1629 Func<TSource, int> selector)
1631 if (source == null || selector == null)
1632 throw new ArgumentNullException ();
1634 int minimum = int.MaxValue;
1636 foreach (TSource item in source) {
1637 int element = selector (item);
1638 if (element < minimum)
1644 throw new InvalidOperationException ();
1650 public static int? Min<TSource> (this IEnumerable<TSource> source,
1651 Func<TSource, int?> selector)
1653 if (source == null || selector == null)
1654 throw new ArgumentNullException ();
1656 bool onlyNull = true;
1657 int? minimum = int.MaxValue;
1658 foreach (TSource item in source) {
1659 int? element = selector (item);
1660 if (element.HasValue) {
1662 if (element < minimum)
1666 return (onlyNull ? null : minimum);
1670 public static long Min<TSource> (this IEnumerable<TSource> source,
1671 Func<TSource, long> selector)
1673 if (source == null || selector == null)
1674 throw new ArgumentNullException ();
1676 long minimum = long.MaxValue;
1678 foreach (TSource item in source) {
1679 long element = selector (item);
1680 if (element < minimum)
1686 throw new InvalidOperationException ();
1692 public static long? Min<TSource> (this IEnumerable<TSource> source,
1693 Func<TSource, long?> selector)
1695 if (source == null || selector == null)
1696 throw new ArgumentNullException ();
1698 bool onlyNull = true;
1699 long? minimum = long.MaxValue;
1700 foreach (TSource item in source) {
1701 long? element = selector (item);
1702 if (element.HasValue) {
1704 if (element < minimum)
1708 return (onlyNull ? null : minimum);
1712 public static double Min<TSource> (this IEnumerable<TSource> source,
1713 Func<TSource, double> selector)
1715 if (source == null || selector == null)
1716 throw new ArgumentNullException ();
1718 double minimum = double.MaxValue;
1720 foreach (TSource item in source) {
1721 double element = selector (item);
1722 if (element < minimum)
1728 throw new InvalidOperationException ();
1734 public static double? Min<TSource> (this IEnumerable<TSource> source,
1735 Func<TSource, double?> selector)
1737 if (source == null || selector == null)
1738 throw new ArgumentNullException ();
1740 bool onlyNull = true;
1741 double? minimum = double.MaxValue;
1742 foreach (TSource item in source) {
1743 double? element = selector (item);
1744 if (element.HasValue) {
1746 if (element < minimum)
1750 return (onlyNull ? null : minimum);
1754 public static decimal Min<TSource> (this IEnumerable<TSource> source,
1755 Func<TSource, decimal> selector)
1757 if (source == null || selector == null)
1758 throw new ArgumentNullException ();
1760 decimal minimum = decimal.MaxValue;
1762 foreach (TSource item in source) {
1763 decimal element = selector (item);
1764 if (element < minimum)
1770 throw new InvalidOperationException ();
1776 public static decimal? Min<TSource> (this IEnumerable<TSource> source,
1777 Func<TSource, decimal?> selector)
1779 if (source == null || selector == null)
1780 throw new ArgumentNullException ();
1782 bool onlyNull = true;
1783 decimal? minimum = decimal.MaxValue;
1784 foreach (TSource item in source) {
1785 decimal? element = selector (item);
1786 if (element.HasValue) {
1788 if (element < minimum)
1792 return (onlyNull ? null : minimum);
1796 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source,
1797 Func<TSource, TResult> selector)
1799 if (source == null || selector == null)
1800 throw new ArgumentNullException ();
1802 bool notAssigned = true;
1803 TResult minimum = default (TResult);
1805 foreach (TSource item in source) {
1806 TResult element = selector (item);
1809 notAssigned = false;
1812 if (element is IComparable<TResult>)
1813 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1814 else if (element is System.IComparable)
1815 comparison = ((System.IComparable) element).CompareTo (minimum);
1817 throw new ArgumentNullException ();
1826 throw new InvalidOperationException ();
1835 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1838 throw new ArgumentNullException ();
1840 foreach (object element in source)
1841 if (element is TResult)
1842 yield return (TResult) element;
1849 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1850 Func<TSource, TKey> keySelector)
1852 return OrderBy<TSource, TKey> (source, keySelector, null);
1856 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1857 Func<TSource, TKey> keySelector,
1858 IComparer<TKey> comparer)
1860 if (source == null || keySelector == null)
1861 throw new ArgumentNullException ();
1863 return new InternalOrderedSequence<TSource, TKey> (
1864 source, keySelector, comparer, false);
1869 #region OrderByDescending
1871 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1872 Func<TSource, TKey> keySelector)
1874 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1878 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1879 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1881 if (source == null || keySelector == null)
1882 throw new ArgumentNullException ();
1884 return new InternalOrderedSequence<TSource, TKey> (
1885 source, keySelector, comparer, true);
1892 public static IEnumerable<int> Range (int start, int count)
1894 if (count < 0 || (start + count - 1) > int.MaxValue)
1895 throw new ArgumentOutOfRangeException ();
1897 for (int i = start; i < (start + count - 1); i++)
1905 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1908 throw new ArgumentOutOfRangeException ();
1910 for (int i = 0; i < count; i++)
1911 yield return element;
1919 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1922 throw new ArgumentNullException ();
1924 List<TSource> list = new List<TSource> (source);
1933 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1934 Func<TSource, TResult> selector)
1936 if (source == null || selector == null)
1937 throw new ArgumentNullException ();
1939 foreach (TSource element in source)
1940 yield return selector (element);
1944 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1945 Func<TSource, int, TResult> selector)
1947 if (source == null || selector == null)
1948 throw new ArgumentNullException ();
1951 foreach (TSource element in source) {
1952 yield return selector (element, counter);
1961 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1962 Func<TSource, IEnumerable<TResult>> selector)
1964 if (source == null || selector == null)
1965 throw new ArgumentNullException ();
1967 foreach (TSource element in source)
1968 foreach (TResult item in selector (element))
1973 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1974 Func<TSource, int, IEnumerable<TResult>> selector)
1976 if (source == null || selector == null)
1977 throw new ArgumentNullException ();
1980 foreach (TSource element in source) {
1981 foreach (TResult item in selector (element, counter++))
1987 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1988 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1990 if (source == null || collectionSelector == null || selector == null)
1991 throw new ArgumentNullException ();
1993 foreach (TSource element in source)
1994 foreach (TCollection collection in collectionSelector (element))
1995 yield return selector (element, collection);
1998 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1999 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
2001 if (source == null || collectionSelector == null || selector == null)
2002 throw new ArgumentNullException ();
2005 foreach (TSource element in source)
2006 foreach (TCollection collection in collectionSelector (element, counter++))
2007 yield return selector (element, collection);
2014 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2017 throw new ArgumentNullException ();
2019 bool otherElement = false;
2020 TSource singleElement = default (TSource);
2021 foreach (TSource element in source) {
2022 if (otherElement) throw new InvalidOperationException ();
2023 if (!otherElement) otherElement = true;
2024 singleElement = element;
2028 return singleElement;
2030 throw new InvalidOperationException ();
2034 public static TSource Single<TSource> (this IEnumerable<TSource> source,
2035 Func<TSource, bool> predicate)
2037 if (source == null || predicate == null)
2038 throw new ArgumentNullException ();
2040 bool otherElement = false;
2041 TSource singleElement = default (TSource);
2042 foreach (TSource element in source) {
2043 if (predicate (element)) {
2044 if (otherElement) throw new InvalidOperationException ();
2045 if (!otherElement) otherElement = true;
2046 singleElement = element;
2051 return singleElement;
2053 throw new InvalidOperationException ();
2058 #region SingleOrDefault
2060 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2063 throw new ArgumentNullException ();
2065 bool otherElement = false;
2066 TSource singleElement = default (TSource);
2067 foreach (TSource element in source) {
2068 if (otherElement) throw new InvalidOperationException ();
2069 if (!otherElement) otherElement = true;
2070 singleElement = element;
2073 return singleElement;
2077 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source,
2078 Func<TSource, bool> predicate)
2080 if (source == null || predicate == null)
2081 throw new ArgumentNullException ();
2083 bool otherElement = false;
2084 TSource singleElement = default (TSource);
2085 foreach (TSource element in source) {
2086 if (predicate (element)) {
2087 if (otherElement) throw new InvalidOperationException ();
2088 if (!otherElement) otherElement = true;
2089 singleElement = element;
2093 return singleElement;
2099 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2102 throw new NotSupportedException ();
2105 foreach (TSource e in source) {
2116 public static IEnumerable<TSource> SkipWhile<TSource> (
2117 this IEnumerable<TSource> source,
2118 Func<TSource, bool> predicate)
2120 if (source == null || predicate == null)
2121 throw new ArgumentNullException ();
2125 foreach (TSource element in source) {
2127 yield return element;
2129 if (!predicate (element)) {
2130 yield return element;
2137 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source,
2138 Func<TSource, int, bool> predicate)
2140 if (source == null || predicate == null)
2141 throw new ArgumentNullException ();
2146 foreach (TSource element in source) {
2148 yield return element;
2150 if (!predicate (element, counter)) {
2151 yield return element;
2162 public static int Sum (this IEnumerable<int> source)
2165 throw new ArgumentNullException ("source");
2168 foreach (int element in source)
2175 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2177 if (source == null || selector == null)
2178 throw new ArgumentNullException ();
2181 foreach (TSource element in source)
2182 sum += selector (element);
2188 public static int? Sum (this IEnumerable<int?> source)
2191 throw new ArgumentNullException ();
2194 foreach (int? element in source)
2195 if (element.HasValue)
2196 sum += element.Value;
2202 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2204 if (source == null || selector == null)
2205 throw new ArgumentNullException ();
2208 foreach (TSource element in source) {
2209 int? item = selector (element);
2218 public static long Sum (this IEnumerable<long> source)
2221 throw new ArgumentNullException ();
2224 foreach (long element in source)
2231 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2233 if (source == null || selector == null)
2234 throw new ArgumentNullException ();
2237 foreach (TSource element in source)
2238 sum += selector (element);
2244 public static long? Sum (this IEnumerable<long?> source)
2247 throw new ArgumentNullException ();
2250 foreach (long? element in source)
2251 if (element.HasValue)
2252 sum += element.Value;
2258 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2260 if (source == null || selector == null)
2261 throw new ArgumentNullException ();
2264 foreach (TSource element in source) {
2265 long? item = selector (element);
2274 public static double Sum (this IEnumerable<double> source)
2277 throw new ArgumentNullException ();
2280 foreach (double element in source)
2287 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2289 if (source == null || selector == null)
2290 throw new ArgumentNullException ();
2293 foreach (TSource element in source)
2294 sum += selector (element);
2300 public static double? Sum (this IEnumerable<double?> source)
2303 throw new ArgumentNullException ();
2306 foreach (double? element in source)
2307 if (element.HasValue)
2308 sum += element.Value;
2314 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2316 if (source == null || selector == null)
2317 throw new ArgumentNullException ();
2320 foreach (TSource element in source) {
2321 double? item = selector (element);
2330 public static decimal Sum (this IEnumerable<decimal> source)
2333 throw new ArgumentNullException ();
2336 foreach (decimal element in source)
2343 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2345 if (source == null || selector == null)
2346 throw new ArgumentNullException ();
2349 foreach (TSource element in source)
2350 sum += selector (element);
2356 public static decimal? Sum (this IEnumerable<decimal?> source)
2359 throw new ArgumentNullException ();
2362 foreach (decimal? element in source)
2363 if (element.HasValue)
2364 sum += element.Value;
2370 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2372 if (source == null || selector == null)
2373 throw new ArgumentNullException ();
2376 foreach (TSource element in source) {
2377 decimal? item = selector (element);
2388 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2391 throw new ArgumentNullException ();
2397 foreach (TSource element in source) {
2398 yield return element;
2400 if (counter == count)
2410 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2412 if (source == null || predicate == null)
2413 throw new ArgumentNullException ();
2415 foreach (TSource element in source) {
2416 if (predicate (element))
2417 yield return element;
2423 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2425 if (source == null || predicate == null)
2426 throw new ArgumentNullException ();
2429 foreach (TSource element in source) {
2430 if (predicate (element, counter))
2431 yield return element;
2442 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2444 return ThenBy<TSource, TKey> (source, keySelector, null);
2448 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2449 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2451 if (source == null || keySelector == null)
2452 throw new ArgumentNullException ();
2454 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2459 #region ThenByDescending
2461 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2462 Func<TSource, TKey> keySelector)
2464 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2468 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2469 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2471 if (source == null || keySelector == null)
2472 throw new ArgumentNullException ();
2474 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2480 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2483 throw new ArgumentNullException ();
2485 List<TSource> list = new List<TSource> (source);
2486 return list.ToArray ();
2491 #region ToDictionary
2492 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2494 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2498 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2501 throw new ArgumentNullException ("source");
2502 if (keySelector == null)
2503 throw new ArgumentNullException ("keySelector");
2504 if (elementSelector == null)
2505 throw new ArgumentNullException ("elementSelector");
2507 Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement> (comparer);
2508 foreach (TSource e in source) {
2509 dict.Add (keySelector (e), elementSelector (e));
2517 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2520 throw new ArgumentNullException ("source");
2522 return new List<TSource> (source);
2528 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2530 return ToLookup<TSource, TKey> (source, keySelector, null);
2534 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2535 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2537 if (source == null || keySelector == null)
2538 throw new ArgumentNullException ();
2540 Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2541 foreach (TSource element in source) {
2542 TKey key = keySelector (element);
2544 throw new ArgumentNullException ();
2545 if (!dictionary.ContainsKey (key))
2546 dictionary.Add (key, new List<TSource> ());
2547 dictionary [key].Add (element);
2549 return new Lookup<TKey, TSource> (dictionary);
2553 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2554 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2556 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2560 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2561 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2563 if (source == null || keySelector == null || elementSelector == null)
2564 throw new ArgumentNullException ();
2566 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2567 foreach (TSource element in source) {
2568 TKey key = keySelector (element);
2570 throw new ArgumentNullException ();
2571 if (!dictionary.ContainsKey (key))
2572 dictionary.Add (key, new List<TElement> ());
2573 dictionary [key].Add (elementSelector (element));
2575 return new Lookup<TKey, TElement> (dictionary);
2582 public static IEnumerable<T> ToSequence<T> (this IEnumerable<T> source)
2584 return (IEnumerable<T>) source;
2592 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2594 if (first == null || second == null)
2595 throw new ArgumentNullException ();
2597 List<TSource> items = new List<TSource> ();
2598 foreach (TSource element in first) {
2599 if (IndexOf (items, element) == -1) {
2600 items.Add (element);
2601 yield return element;
2604 foreach (TSource element in second) {
2605 if (IndexOf (items, element) == -1) {
2606 items.Add (element);
2607 yield return element;
2616 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2617 Func<TSource, bool> predicate)
2619 if (source == null || predicate == null)
2620 throw new ArgumentNullException ();
2622 foreach (TSource element in source)
2623 if (predicate (element))
2624 yield return element;
2628 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2629 Func<TSource, int, bool> predicate)
2631 if (source == null || predicate == null)
2632 throw new ArgumentNullException ();
2635 foreach (TSource element in source) {
2636 if (predicate (element, counter))
2637 yield return element;
2644 // These methods are not included in the
2645 // .NET Standard Query Operators Specification,
2646 // but they provide additional useful commands
2650 private static bool Equals<T> (T first, T second)
2652 // Mostly, values in Enumerable<T>
2653 // sequences need to be compared using
2654 // Equals and GetHashCode
2656 if (first == null || second == null)
2657 return (first == null && second == null);
2659 return ((first.Equals (second) ||
2660 first.GetHashCode () == second.GetHashCode ()));
2667 static int IndexOf<T> (this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2669 if (comparer == null)
2670 comparer = EqualityComparer<T>.Default;
2673 foreach (T element in source) {
2674 if (comparer.Equals (element, item))
2678 // The item was not found
2682 static int IndexOf<T> (this IEnumerable<T> source, T item)
2684 return IndexOf<T> (source, item, null);
2688 #region ToReadOnlyCollection
2689 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (IEnumerable<TSource> source)
2692 return new ReadOnlyCollection<TSource> (new List<TSource> ());
2694 if (typeof (ReadOnlyCollection<TSource>).IsInstanceOfType (source))
2695 return source as ReadOnlyCollection<TSource>;
2697 return new ReadOnlyCollection<TSource> (ToArray<TSource> (source));