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)
23 // Jb Evain (jbevain@novell.com)
26 // precious: http://www.hookedonlinq.com
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
35 public static class Enumerable
38 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
41 throw new ArgumentNullException ("source");
43 throw new ArgumentNullException ("func");
45 // custom foreach so that we can efficiently throw an exception
46 // if zero elements and treat the first element differently
47 using (var enumerator = source.GetEnumerator ()) {
48 if (!enumerator.MoveNext ())
49 throw new InvalidOperationException ("No elements in source list");
51 TSource folded = enumerator.Current;
52 while (enumerator.MoveNext ())
53 folded = func (folded, enumerator.Current);
59 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
60 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
62 if (source == null || func == null)
63 throw new ArgumentNullException ();
65 TAccumulate folded = seed;
66 foreach (TSource element in source)
67 folded = func (folded, element);
72 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
75 throw new ArgumentNullException ("source");
77 throw new ArgumentNullException ("func");
78 if (resultSelector == null)
79 throw new ArgumentNullException ("resultSelector");
81 TAccumulate result = seed;
82 foreach (TSource e in source)
83 result = func (result, e);
84 return resultSelector (result);
89 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
91 if (source == null || predicate == null)
92 throw new ArgumentNullException ();
94 foreach (TSource element in source)
95 if (!predicate (element))
102 public static bool Any<TSource> (this IEnumerable<TSource> source)
105 throw new ArgumentNullException ();
107 foreach (TSource element in source)
113 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
115 if (source == null || predicate == null)
116 throw new ArgumentNullException ();
118 foreach (TSource element in source)
119 if (predicate (element))
126 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
133 public static double Average (this IEnumerable<int> source)
136 throw new ArgumentNullException ();
140 foreach (int element in source) {
146 throw new InvalidOperationException ();
148 return (double) sum / (double) counter;
152 public static double? Average (this IEnumerable<int?> source)
155 throw new ArgumentNullException ();
157 bool onlyNull = true;
160 foreach (int? element in source) {
161 if (element.HasValue) {
163 sum += element.Value;
167 return (onlyNull ? null : (double?) sum / (double?) counter);
171 public static double Average (this IEnumerable<long> source)
174 throw new ArgumentNullException ();
178 foreach (long element in source) {
184 throw new InvalidOperationException ();
186 return (double) sum / (double) counter;
190 public static double? Average (this IEnumerable<long?> source)
193 throw new ArgumentNullException ();
195 bool onlyNull = true;
198 foreach (long? element in source) {
199 if (element.HasValue) {
201 sum += element.Value;
205 return (onlyNull ? null : (double?) sum / (double?) counter);
209 public static double Average (this IEnumerable<double> source)
212 throw new ArgumentNullException ();
216 foreach (double element in source) {
222 throw new InvalidOperationException ();
224 return sum / counter;
228 public static double? Average (this IEnumerable<double?> source)
231 throw new ArgumentNullException ();
233 bool onlyNull = true;
236 foreach (double? element in source) {
237 if (element.HasValue) {
239 sum += element.Value;
243 return (onlyNull ? null : (double?) (sum / counter));
247 public static decimal Average (this IEnumerable<decimal> source)
250 throw new ArgumentNullException ();
254 foreach (decimal element in source) {
260 throw new InvalidOperationException ();
262 return sum / counter;
266 public static decimal? Average (this IEnumerable<decimal?> source)
269 throw new ArgumentNullException ();
271 bool onlyNull = true;
274 foreach (decimal? element in source) {
275 if (element.HasValue) {
277 sum += element.Value;
281 return (onlyNull ? null : (decimal?) (sum / counter));
285 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
287 if (source == null || selector == null)
288 throw new ArgumentNullException ();
292 foreach (TSource item in source) {
293 sum += selector (item);
298 throw new InvalidOperationException ();
300 return (double) sum / (double) counter;
304 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
306 if (source == null || selector == null)
307 throw new ArgumentNullException ();
309 bool onlyNull = true;
312 foreach (TSource item in source) {
313 int? element = selector (item);
314 if (element.HasValue) {
316 sum += element.Value;
320 return (onlyNull ? null : (double?) sum / (double?) counter);
324 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
326 if (source == null || selector == null)
327 throw new ArgumentNullException ();
331 foreach (TSource item in source) {
332 sum += selector (item);
337 throw new InvalidOperationException ();
339 return (double) sum / (double) counter;
343 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
345 if (source == null || selector == null)
346 throw new ArgumentNullException ();
348 bool onlyNull = true;
351 foreach (TSource item in source) {
352 long? element = selector (item);
353 if (element.HasValue) {
355 sum += element.Value;
359 return (onlyNull ? null : (double?) sum / (double?) counter);
363 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
365 if (source == null || selector == null)
366 throw new ArgumentNullException ();
370 foreach (TSource item in source) {
371 sum += selector (item);
376 throw new InvalidOperationException ();
378 return sum / counter;
382 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
384 if (source == null || selector == null)
385 throw new ArgumentNullException ();
387 bool onlyNull = true;
390 foreach (TSource item in source) {
391 double? element = selector (item);
392 if (element.HasValue) {
394 sum += element.Value;
398 return (onlyNull ? null : (double?) (sum / counter));
402 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
404 if (source == null || selector == null)
405 throw new ArgumentNullException ();
409 foreach (TSource item in source) {
410 sum += selector (item);
415 throw new InvalidOperationException ();
417 return sum / counter;
421 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
423 if (source == null || selector == null)
424 throw new ArgumentNullException ();
426 bool onlyNull = true;
429 foreach (TSource item in source) {
430 decimal? element = selector (item);
431 if (element.HasValue) {
433 sum += element.Value;
437 return (onlyNull ? null : (decimal?) (sum / counter));
442 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
445 throw new ArgumentNullException ();
447 foreach (object element in source)
448 yield return (TResult) element;
453 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
455 if (first == null || second == null)
456 throw new ArgumentNullException ();
458 foreach (TSource element in first)
459 yield return element;
460 foreach (TSource element in second)
461 yield return element;
468 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
470 var collection = source as ICollection<TSource>;
471 if (collection != null)
472 return collection.Contains (value);
474 return Contains<TSource> (source, value, null);
477 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
480 throw new ArgumentNullException ("source");
482 if (comparer == null)
483 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 var collection = source as ICollection<TSource>;
501 if (collection != null)
502 return collection.Count;
505 foreach (var 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 (var 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));
532 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
535 throw new ArgumentNullException ("source");
538 foreach (TSource item in source) {
544 yield return defaultValue;
551 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
553 return Distinct<TSource> (source, null);
556 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
559 throw new ArgumentNullException ();
561 if (comparer == null)
562 comparer = EqualityComparer<TSource>.Default;
564 var items = new List<TSource> (); // TODO: use a HashSet here
565 foreach (var element in source) {
566 if (! items.Contains (element, comparer)) {
568 yield return element;
576 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
579 throw new ArgumentNullException ();
581 throw new ArgumentOutOfRangeException ();
583 var list = source as IList<TSource>;
588 foreach (var element in source) {
589 if (counter == index)
594 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 var list = source as IList<TSource>;
610 return index < list.Count ? list [index] : default (TSource);
613 foreach (TSource element in source) {
614 if (counter == index)
619 return default (TSource);
625 public static IEnumerable<TResult> Empty<TResult> ()
627 return new TResult [0];
633 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
635 return Except (first, second, null);
638 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
640 if (first == null || second == null)
641 throw new ArgumentNullException ();
643 if (comparer == null)
644 comparer = EqualityComparer<TSource>.Default;
646 var items = new List<TSource> (Distinct (second));
647 foreach (TSource element in first) {
648 if (! items.Contains (element, comparer))
649 yield return element;
657 public static TSource First<TSource> (this IEnumerable<TSource> source)
660 throw new ArgumentNullException ();
662 foreach (TSource element in source)
665 throw new InvalidOperationException ();
669 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
671 if (source == null || predicate == null)
672 throw new ArgumentNullException ();
674 foreach (TSource element in source) {
675 if (predicate (element))
679 throw new InvalidOperationException ();
684 #region FirstOrDefault
686 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
689 throw new ArgumentNullException ();
691 foreach (TSource element in source)
694 return default (TSource);
698 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
700 if (source == null || predicate == null)
701 throw new ArgumentNullException ();
703 foreach (TSource element in source) {
704 if (predicate (element))
708 return default (TSource);
715 private static List<T> ContainsGroup<K, T> (
716 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
718 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
719 foreach (KeyValuePair<K, List<T>> value in items) {
720 if (comparerInUse.Equals (value.Key, key))
727 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
728 Func<TSource, TKey> keySelector)
730 return GroupBy<TSource, TKey> (source, keySelector, null);
734 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
735 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
737 if (source == null || keySelector == null)
738 throw new ArgumentNullException ();
740 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
741 List<TSource> nullList = new List<TSource> ();
743 int nullCounter = -1;
745 foreach (TSource element in source) {
746 TKey key = keySelector (element);
748 nullList.Add (element);
749 if (nullCounter == -1) {
750 nullCounter = counter;
754 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
756 group = new List<TSource> ();
757 groups.Add (key, group);
765 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
766 if (counter == nullCounter) {
767 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
768 yield return nullGroup;
771 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
772 yield return grouping;
778 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
779 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
781 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
785 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
786 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
788 if (source == null || keySelector == null || elementSelector == null)
789 throw new ArgumentNullException ();
791 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
792 List<TElement> nullList = new List<TElement> ();
794 int nullCounter = -1;
796 foreach (TSource item in source) {
797 TKey key = keySelector (item);
798 TElement element = elementSelector (item);
800 nullList.Add (element);
801 if (nullCounter == -1) {
802 nullCounter = counter;
806 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
808 group = new List<TElement> ();
809 groups.Add (key, group);
817 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
818 if (counter == nullCounter) {
819 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
820 yield return nullGroup;
823 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
824 yield return grouping;
833 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
834 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
835 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
837 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
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,
843 IEqualityComparer<TKey> comparer)
845 if (outer == null || inner == null || outerKeySelector == null ||
846 innerKeySelector == null || resultSelector == null)
847 throw new ArgumentNullException ();
849 if (comparer == null)
850 comparer = EqualityComparer<TKey>.Default;
852 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
853 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
854 foreach (U element in inner)
856 K innerKey = innerKeySelector (element);
857 if (!innerKeys.ContainsKey (innerKey))
858 innerKeys.Add (innerKey, new List<U> ());
859 innerKeys[innerKey].Add (element);
862 foreach (TOuter element in outer) {
863 TKey outerKey = outerKeySelector (element);
864 if (innerKeys.Contains (outerKey))
865 yield return resultSelector (element, innerKeys [outerKey]);
867 yield return resultSelector (element, Empty<TInner> ());
875 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
877 return Intersect (first, second, null);
880 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
882 if (first == null || second == null)
883 throw new ArgumentNullException ();
885 if (comparer == null)
886 comparer = EqualityComparer<TSource>.Default;
888 List<TSource> items = new List<TSource> (Distinct (first));
889 foreach (TSource element in second) {
890 if (Contains (items, element, comparer))
891 yield return element;
899 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
900 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
901 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
903 if (outer == null || inner == null || outerKeySelector == null ||
904 innerKeySelector == null || resultSelector == null)
905 throw new ArgumentNullException ();
907 if (comparer == null)
908 comparer = EqualityComparer<TKey>.Default;
910 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
911 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
912 foreach (U element in inner)
914 K innerKey = innerKeySelector (element);
915 if (!innerKeys.ContainsKey (innerKey))
916 innerKeys.Add (innerKey, new List<U> ());
917 innerKeys[innerKey].Add (element);
920 foreach (TOuter element in outer) {
921 TKey outerKey = outerKeySelector (element);
922 if (innerKeys.Contains (outerKey)) {
923 foreach (TInner innerElement in innerKeys [outerKey])
924 yield return resultSelector (element, innerElement);
929 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
930 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
931 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
933 return Join<TOuter, TInner, TKey, TResult> (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
939 public static TSource Last<TSource> (this IEnumerable<TSource> source)
942 throw new ArgumentNullException ();
944 bool noElements = true;
945 TSource lastElement = default (TSource);
946 foreach (TSource element in source) {
947 if (noElements) noElements = false;
948 lastElement = element;
954 throw new InvalidOperationException ();
957 public static TSource Last<TSource> (this IEnumerable<TSource> source,
958 Func<TSource, bool> predicate)
960 if (source == null || predicate == null)
961 throw new ArgumentNullException ();
963 bool noElements = true;
964 TSource lastElement = default (TSource);
965 foreach (TSource element in source) {
966 if (predicate (element)) {
967 if (noElements) noElements = false;
968 lastElement = element;
975 throw new InvalidOperationException ();
980 #region LastOrDefault
982 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
985 throw new ArgumentNullException ();
987 var list = source as IList<TSource>;
989 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
991 TSource lastElement = default (TSource);
992 foreach (TSource element in source)
993 lastElement = element;
998 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source,
999 Func<TSource, bool> predicate)
1001 if (source == null || predicate == null)
1002 throw new ArgumentNullException ();
1004 TSource lastElement = default (TSource);
1005 foreach (TSource element in source) {
1006 if (predicate (element))
1007 lastElement = element;
1016 public static long LongCount<TSource> (this IEnumerable<TSource> source)
1019 throw new ArgumentNullException ();
1022 foreach (TSource element in source)
1028 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1030 if (source == null || selector == null)
1031 throw new ArgumentNullException ();
1034 foreach (TSource element in source)
1035 if (selector (element))
1045 public static int Max (this IEnumerable<int> source)
1048 throw new ArgumentNullException ();
1050 int maximum = int.MinValue;
1052 foreach (int element in source) {
1053 if (element > maximum)
1059 throw new InvalidOperationException ();
1065 public static int? Max (this IEnumerable<int?> source)
1068 throw new ArgumentNullException ();
1070 bool onlyNull = true;
1071 int? maximum = int.MinValue;
1072 foreach (int? element in source) {
1073 if (element.HasValue) {
1075 if (element > maximum)
1079 return (onlyNull ? null : maximum);
1083 public static long Max (this IEnumerable<long> source)
1086 throw new ArgumentNullException ();
1088 long maximum = long.MinValue;
1090 foreach (long element in source) {
1091 if (element > maximum)
1097 throw new InvalidOperationException ();
1103 public static long? Max (this IEnumerable<long?> source)
1106 throw new ArgumentNullException ();
1108 bool onlyNull = true;
1109 long? maximum = long.MinValue;
1110 foreach (long? element in source) {
1111 if (element.HasValue) {
1113 if (element > maximum)
1117 return (onlyNull ? null : maximum);
1121 public static double Max (this IEnumerable<double> source)
1124 throw new ArgumentNullException ();
1126 double maximum = double.MinValue;
1128 foreach (double element in source) {
1129 if (element > maximum)
1135 throw new InvalidOperationException ();
1141 public static double? Max (this IEnumerable<double?> source)
1144 throw new ArgumentNullException ();
1146 bool onlyNull = true;
1147 double? maximum = double.MinValue;
1148 foreach (double? element in source) {
1149 if (element.HasValue) {
1151 if (element > maximum)
1155 return (onlyNull ? null : maximum);
1159 public static decimal Max (this IEnumerable<decimal> source)
1162 throw new ArgumentNullException ();
1164 decimal maximum = decimal.MinValue;
1166 foreach (decimal element in source) {
1167 if (element > maximum)
1173 throw new InvalidOperationException ();
1179 public static decimal? Max (this IEnumerable<decimal?> source)
1182 throw new ArgumentNullException ();
1184 bool onlyNull = true;
1185 decimal? maximum = decimal.MinValue;
1186 foreach (decimal? element in source) {
1187 if (element.HasValue) {
1189 if (element > maximum)
1193 return (onlyNull ? null : maximum);
1197 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1200 throw new ArgumentNullException ();
1202 bool notAssigned = true;
1203 TSource maximum = default (TSource);
1205 foreach (TSource element in source) {
1208 notAssigned = false;
1211 if (element is IComparable<TSource>)
1212 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1213 else if (element is System.IComparable)
1214 comparison = ((System.IComparable) element).CompareTo (maximum);
1216 throw new ArgumentNullException ();
1225 throw new InvalidOperationException ();
1231 public static int Max<TSource> (this IEnumerable<TSource> source,
1232 Func<TSource, int> selector)
1234 if (source == null || selector == null)
1235 throw new ArgumentNullException ();
1237 int maximum = int.MinValue;
1239 foreach (TSource item in source) {
1240 int element = selector (item);
1241 if (element > maximum)
1247 throw new InvalidOperationException ();
1253 public static int? Max<TSource> (this IEnumerable<TSource> source,
1254 Func<TSource, int?> selector)
1256 if (source == null || selector == null)
1257 throw new ArgumentNullException ();
1259 bool onlyNull = true;
1260 int? maximum = int.MinValue;
1261 foreach (TSource item in source) {
1262 int? element = selector (item);
1263 if (element.HasValue) {
1265 if (element > maximum)
1269 return (onlyNull ? null : maximum);
1273 public static long Max<TSource> (this IEnumerable<TSource> source,
1274 Func<TSource, long> selector)
1276 if (source == null || selector == null)
1277 throw new ArgumentNullException ();
1279 long maximum = long.MinValue;
1281 foreach (TSource item in source) {
1282 long element = selector (item);
1283 if (element > maximum)
1289 throw new InvalidOperationException ();
1295 public static long? Max<TSource> (this IEnumerable<TSource> source,
1296 Func<TSource, long?> selector)
1298 if (source == null || selector == null)
1299 throw new ArgumentNullException ();
1301 bool onlyNull = true;
1302 long? maximum = long.MinValue;
1303 foreach (TSource item in source) {
1304 long? element = selector (item);
1305 if (element.HasValue) {
1307 if (element > maximum)
1311 return (onlyNull ? null : maximum);
1315 public static double Max<TSource> (this IEnumerable<TSource> source,
1316 Func<TSource, double> selector)
1318 if (source == null || selector == null)
1319 throw new ArgumentNullException ();
1321 double maximum = double.MinValue;
1323 foreach (TSource item in source) {
1324 double element = selector (item);
1325 if (element > maximum)
1331 throw new InvalidOperationException ();
1337 public static double? Max<TSource> (this IEnumerable<TSource> source,
1338 Func<TSource, double?> selector)
1340 if (source == null || selector == null)
1341 throw new ArgumentNullException ();
1343 bool onlyNull = true;
1344 double? maximum = double.MinValue;
1345 foreach (TSource item in source) {
1346 double? element = selector (item);
1347 if (element.HasValue) {
1349 if (element > maximum)
1353 return (onlyNull ? null : maximum);
1357 public static decimal Max<TSource> (this IEnumerable<TSource> source,
1358 Func<TSource, decimal> selector)
1360 if (source == null || selector == null)
1361 throw new ArgumentNullException ();
1363 decimal maximum = decimal.MinValue;
1365 foreach (TSource item in source) {
1366 decimal element = selector (item);
1367 if (element > maximum)
1373 throw new InvalidOperationException ();
1379 public static decimal? Max<TSource> (this IEnumerable<TSource> source,
1380 Func<TSource, decimal?> selector)
1382 if (source == null || selector == null)
1383 throw new ArgumentNullException ();
1385 bool onlyNull = true;
1386 decimal? maximum = decimal.MinValue;
1387 foreach (TSource item in source) {
1388 decimal? element = selector (item);
1389 if (element.HasValue) {
1391 if (element > maximum)
1395 return (onlyNull ? null : maximum);
1399 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source,
1400 Func<TSource, TResult> selector)
1402 if (source == null || selector == null)
1403 throw new ArgumentNullException ();
1405 bool notAssigned = true;
1406 TResult maximum = default (TResult);
1408 foreach (TSource item in source) {
1409 TResult element = selector (item);
1412 notAssigned = false;
1415 if (element is IComparable<TResult>)
1416 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1417 else if (element is System.IComparable)
1418 comparison = ((System.IComparable) element).CompareTo (maximum);
1420 throw new ArgumentNullException ();
1429 throw new InvalidOperationException ();
1438 public static int Min (this IEnumerable<int> source)
1441 throw new ArgumentNullException ();
1443 int minimum = int.MaxValue;
1445 foreach (int element in source) {
1446 if (element < minimum)
1452 throw new InvalidOperationException ();
1458 public static int? Min (this IEnumerable<int?> source)
1461 throw new ArgumentNullException ();
1463 bool onlyNull = true;
1464 int? minimum = int.MaxValue;
1465 foreach (int? element in source) {
1466 if (element.HasValue) {
1468 if (element < minimum)
1472 return (onlyNull ? null : minimum);
1475 public static long Min (this IEnumerable<long> source)
1478 throw new ArgumentNullException ();
1480 long minimum = long.MaxValue;
1482 foreach (long element in source) {
1483 if (element < minimum)
1489 throw new InvalidOperationException ();
1495 public static long? Min (this IEnumerable<long?> source)
1498 throw new ArgumentNullException ();
1500 bool onlyNull = true;
1501 long? minimum = long.MaxValue;
1502 foreach (long? element in source) {
1503 if (element.HasValue) {
1505 if (element < minimum)
1509 return (onlyNull ? null : minimum);
1513 public static double Min (this IEnumerable<double> source)
1516 throw new ArgumentNullException ();
1518 double minimum = double.MaxValue;
1520 foreach (double element in source) {
1521 if (element < minimum)
1527 throw new InvalidOperationException ();
1533 public static double? Min (this IEnumerable<double?> source)
1536 throw new ArgumentNullException ();
1538 bool onlyNull = true;
1539 double? minimum = double.MaxValue;
1540 foreach (double? element in source) {
1541 if (element.HasValue) {
1543 if (element < minimum)
1547 return (onlyNull ? null : minimum);
1551 public static decimal Min (this IEnumerable<decimal> source)
1554 throw new ArgumentNullException ();
1556 decimal minimum = decimal.MaxValue;
1558 foreach (decimal element in source) {
1559 if (element < minimum)
1565 throw new InvalidOperationException ();
1571 public static decimal? Min (this IEnumerable<decimal?> source)
1574 throw new ArgumentNullException ();
1576 bool onlyNull = true;
1577 decimal? minimum = decimal.MaxValue;
1578 foreach (decimal? element in source) {
1579 if (element.HasValue) {
1581 if (element < minimum)
1585 return (onlyNull ? null : minimum);
1589 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1592 throw new ArgumentNullException ();
1594 bool notAssigned = true;
1595 TSource minimum = default (TSource);
1597 foreach (TSource element in source) {
1600 notAssigned = false;
1603 if (element is IComparable<TSource>)
1604 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1605 else if (element is System.IComparable)
1606 comparison = ((System.IComparable) element).CompareTo (minimum);
1608 throw new ArgumentNullException ();
1617 throw new InvalidOperationException ();
1623 public static int Min<TSource> (this IEnumerable<TSource> source,
1624 Func<TSource, int> selector)
1626 if (source == null || selector == null)
1627 throw new ArgumentNullException ();
1629 int minimum = int.MaxValue;
1631 foreach (TSource item in source) {
1632 int element = selector (item);
1633 if (element < minimum)
1639 throw new InvalidOperationException ();
1645 public static int? Min<TSource> (this IEnumerable<TSource> source,
1646 Func<TSource, int?> selector)
1648 if (source == null || selector == null)
1649 throw new ArgumentNullException ();
1651 bool onlyNull = true;
1652 int? minimum = int.MaxValue;
1653 foreach (TSource item in source) {
1654 int? element = selector (item);
1655 if (element.HasValue) {
1657 if (element < minimum)
1661 return (onlyNull ? null : minimum);
1665 public static long Min<TSource> (this IEnumerable<TSource> source,
1666 Func<TSource, long> selector)
1668 if (source == null || selector == null)
1669 throw new ArgumentNullException ();
1671 long minimum = long.MaxValue;
1673 foreach (TSource item in source) {
1674 long element = selector (item);
1675 if (element < minimum)
1681 throw new InvalidOperationException ();
1687 public static long? Min<TSource> (this IEnumerable<TSource> source,
1688 Func<TSource, long?> selector)
1690 if (source == null || selector == null)
1691 throw new ArgumentNullException ();
1693 bool onlyNull = true;
1694 long? minimum = long.MaxValue;
1695 foreach (TSource item in source) {
1696 long? element = selector (item);
1697 if (element.HasValue) {
1699 if (element < minimum)
1703 return (onlyNull ? null : minimum);
1707 public static double Min<TSource> (this IEnumerable<TSource> source,
1708 Func<TSource, double> selector)
1710 if (source == null || selector == null)
1711 throw new ArgumentNullException ();
1713 double minimum = double.MaxValue;
1715 foreach (TSource item in source) {
1716 double element = selector (item);
1717 if (element < minimum)
1723 throw new InvalidOperationException ();
1729 public static double? Min<TSource> (this IEnumerable<TSource> source,
1730 Func<TSource, double?> selector)
1732 if (source == null || selector == null)
1733 throw new ArgumentNullException ();
1735 bool onlyNull = true;
1736 double? minimum = double.MaxValue;
1737 foreach (TSource item in source) {
1738 double? element = selector (item);
1739 if (element.HasValue) {
1741 if (element < minimum)
1745 return (onlyNull ? null : minimum);
1749 public static decimal Min<TSource> (this IEnumerable<TSource> source,
1750 Func<TSource, decimal> selector)
1752 if (source == null || selector == null)
1753 throw new ArgumentNullException ();
1755 decimal minimum = decimal.MaxValue;
1757 foreach (TSource item in source) {
1758 decimal element = selector (item);
1759 if (element < minimum)
1765 throw new InvalidOperationException ();
1771 public static decimal? Min<TSource> (this IEnumerable<TSource> source,
1772 Func<TSource, decimal?> selector)
1774 if (source == null || selector == null)
1775 throw new ArgumentNullException ();
1777 bool onlyNull = true;
1778 decimal? minimum = decimal.MaxValue;
1779 foreach (TSource item in source) {
1780 decimal? element = selector (item);
1781 if (element.HasValue) {
1783 if (element < minimum)
1787 return (onlyNull ? null : minimum);
1791 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source,
1792 Func<TSource, TResult> selector)
1794 if (source == null || selector == null)
1795 throw new ArgumentNullException ();
1797 bool notAssigned = true;
1798 TResult minimum = default (TResult);
1800 foreach (TSource item in source) {
1801 TResult element = selector (item);
1804 notAssigned = false;
1807 if (element is IComparable<TResult>)
1808 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1809 else if (element is System.IComparable)
1810 comparison = ((System.IComparable) element).CompareTo (minimum);
1812 throw new ArgumentNullException ();
1821 throw new InvalidOperationException ();
1830 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1833 throw new ArgumentNullException ();
1835 foreach (object element in source)
1836 if (element is TResult)
1837 yield return (TResult) element;
1844 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1845 Func<TSource, TKey> keySelector)
1847 return OrderBy<TSource, TKey> (source, keySelector, null);
1851 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1852 Func<TSource, TKey> keySelector,
1853 IComparer<TKey> comparer)
1855 if (source == null || keySelector == null)
1856 throw new ArgumentNullException ();
1858 return new InternalOrderedSequence<TSource, TKey> (
1859 source, keySelector, comparer, false);
1864 #region OrderByDescending
1866 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1867 Func<TSource, TKey> keySelector)
1869 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1873 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1874 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1876 if (source == null || keySelector == null)
1877 throw new ArgumentNullException ();
1879 return new InternalOrderedSequence<TSource, TKey> (
1880 source, keySelector, comparer, true);
1887 public static IEnumerable<int> Range (int start, int count)
1889 int upto = (start + count - 1);
1891 if (count < 0 || upto > int.MaxValue)
1892 throw new ArgumentOutOfRangeException ();
1894 for (int i = start; i < upto; i++)
1902 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1905 throw new ArgumentOutOfRangeException ();
1907 for (int i = 0; i < count; i++)
1908 yield return element;
1916 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1919 throw new ArgumentNullException ();
1921 List<TSource> list = new List<TSource> (source);
1930 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1931 Func<TSource, TResult> selector)
1933 if (source == null || selector == null)
1934 throw new ArgumentNullException ();
1936 foreach (TSource element in source)
1937 yield return selector (element);
1941 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source,
1942 Func<TSource, int, TResult> selector)
1944 if (source == null || selector == null)
1945 throw new ArgumentNullException ();
1948 foreach (TSource element in source) {
1949 yield return selector (element, counter);
1958 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1959 Func<TSource, IEnumerable<TResult>> selector)
1961 if (source == null || selector == null)
1962 throw new ArgumentNullException ();
1964 foreach (TSource element in source)
1965 foreach (TResult item in selector (element))
1970 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source,
1971 Func<TSource, int, IEnumerable<TResult>> selector)
1973 if (source == null || selector == null)
1974 throw new ArgumentNullException ();
1977 foreach (TSource element in source) {
1978 foreach (TResult item in selector (element, counter++))
1984 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1985 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1987 if (source == null || collectionSelector == null || selector == null)
1988 throw new ArgumentNullException ();
1990 foreach (TSource element in source)
1991 foreach (TCollection collection in collectionSelector (element))
1992 yield return selector (element, collection);
1995 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1996 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1998 if (source == null || collectionSelector == null || selector == null)
1999 throw new ArgumentNullException ();
2002 foreach (TSource element in source)
2003 foreach (TCollection collection in collectionSelector (element, counter++))
2004 yield return selector (element, collection);
2011 public static TSource Single<TSource> (this IEnumerable<TSource> source)
2014 throw new ArgumentNullException ();
2016 bool otherElement = false;
2017 TSource singleElement = default (TSource);
2018 foreach (TSource element in source) {
2019 if (otherElement) throw new InvalidOperationException ();
2020 if (!otherElement) otherElement = true;
2021 singleElement = element;
2025 return singleElement;
2027 throw new InvalidOperationException ();
2031 public static TSource Single<TSource> (this IEnumerable<TSource> source,
2032 Func<TSource, bool> predicate)
2034 if (source == null || predicate == null)
2035 throw new ArgumentNullException ();
2037 bool otherElement = false;
2038 TSource singleElement = default (TSource);
2039 foreach (TSource element in source) {
2040 if (predicate (element)) {
2041 if (otherElement) throw new InvalidOperationException ();
2042 if (!otherElement) otherElement = true;
2043 singleElement = element;
2048 return singleElement;
2050 throw new InvalidOperationException ();
2055 #region SingleOrDefault
2057 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
2060 throw new ArgumentNullException ();
2062 bool otherElement = false;
2063 TSource singleElement = default (TSource);
2064 foreach (TSource element in source) {
2065 if (otherElement) throw new InvalidOperationException ();
2066 if (!otherElement) otherElement = true;
2067 singleElement = element;
2070 return singleElement;
2074 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source,
2075 Func<TSource, bool> predicate)
2077 if (source == null || predicate == null)
2078 throw new ArgumentNullException ();
2080 bool otherElement = false;
2081 TSource singleElement = default (TSource);
2082 foreach (TSource element in source) {
2083 if (predicate (element)) {
2084 if (otherElement) throw new InvalidOperationException ();
2085 if (!otherElement) otherElement = true;
2086 singleElement = element;
2090 return singleElement;
2096 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
2099 throw new NotSupportedException ();
2102 foreach (TSource e in source) {
2113 public static IEnumerable<TSource> SkipWhile<TSource> (
2114 this IEnumerable<TSource> source,
2115 Func<TSource, bool> predicate)
2117 if (source == null || predicate == null)
2118 throw new ArgumentNullException ();
2122 foreach (TSource element in source) {
2124 yield return element;
2126 if (!predicate (element)) {
2127 yield return element;
2133 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source,
2134 Func<TSource, int, bool> predicate)
2136 if (source == null || predicate == null)
2137 throw new ArgumentNullException ();
2142 foreach (TSource element in source) {
2144 yield return element;
2146 if (!predicate (element, counter)) {
2147 yield return element;
2158 public static int Sum (this IEnumerable<int> source)
2161 throw new ArgumentNullException ("source");
2164 foreach (int element in source)
2170 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
2172 if (source == null || selector == null)
2173 throw new ArgumentNullException ();
2176 foreach (TSource element in source)
2177 sum += selector (element);
2183 public static int? Sum (this IEnumerable<int?> source)
2186 throw new ArgumentNullException ();
2189 foreach (int? element in source)
2190 if (element.HasValue)
2191 sum += element.Value;
2197 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
2199 if (source == null || selector == null)
2200 throw new ArgumentNullException ();
2203 foreach (TSource element in source) {
2204 int? item = selector (element);
2213 public static long Sum (this IEnumerable<long> source)
2216 throw new ArgumentNullException ();
2219 foreach (long element in source)
2226 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
2228 if (source == null || selector == null)
2229 throw new ArgumentNullException ();
2232 foreach (TSource element in source)
2233 sum += selector (element);
2239 public static long? Sum (this IEnumerable<long?> source)
2242 throw new ArgumentNullException ();
2245 foreach (long? element in source)
2246 if (element.HasValue)
2247 sum += element.Value;
2253 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
2255 if (source == null || selector == null)
2256 throw new ArgumentNullException ();
2259 foreach (TSource element in source) {
2260 long? item = selector (element);
2269 public static double Sum (this IEnumerable<double> source)
2272 throw new ArgumentNullException ();
2275 foreach (double element in source)
2282 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
2284 if (source == null || selector == null)
2285 throw new ArgumentNullException ();
2288 foreach (TSource element in source)
2289 sum += selector (element);
2295 public static double? Sum (this IEnumerable<double?> source)
2298 throw new ArgumentNullException ();
2301 foreach (double? element in source)
2302 if (element.HasValue)
2303 sum += element.Value;
2309 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
2311 if (source == null || selector == null)
2312 throw new ArgumentNullException ();
2315 foreach (TSource element in source) {
2316 double? item = selector (element);
2325 public static decimal Sum (this IEnumerable<decimal> source)
2328 throw new ArgumentNullException ();
2331 foreach (decimal element in source)
2338 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2340 if (source == null || selector == null)
2341 throw new ArgumentNullException ();
2344 foreach (TSource element in source)
2345 sum += selector (element);
2351 public static decimal? Sum (this IEnumerable<decimal?> source)
2354 throw new ArgumentNullException ();
2357 foreach (decimal? element in source)
2358 if (element.HasValue)
2359 sum += element.Value;
2365 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2367 if (source == null || selector == null)
2368 throw new ArgumentNullException ();
2371 foreach (TSource element in source) {
2372 decimal? item = selector (element);
2383 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2386 throw new ArgumentNullException ();
2392 foreach (TSource element in source) {
2393 yield return element;
2395 if (counter == count)
2405 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2407 if (source == null || predicate == null)
2408 throw new ArgumentNullException ();
2410 foreach (TSource element in source) {
2411 if (predicate (element))
2412 yield return element;
2418 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2420 if (source == null || predicate == null)
2421 throw new ArgumentNullException ();
2424 foreach (TSource element in source) {
2425 if (predicate (element, counter))
2426 yield return element;
2437 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2439 return ThenBy<TSource, TKey> (source, keySelector, null);
2443 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2444 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2446 if (source == null || keySelector == null)
2447 throw new ArgumentNullException ();
2449 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2454 #region ThenByDescending
2456 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2457 Func<TSource, TKey> keySelector)
2459 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2463 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2464 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2466 if (source == null || keySelector == null)
2467 throw new ArgumentNullException ();
2469 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2475 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2478 throw new ArgumentNullException ();
2480 List<TSource> list = new List<TSource> (source);
2481 return list.ToArray ();
2486 #region ToDictionary
2487 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2489 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2493 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2496 throw new ArgumentNullException ("source");
2497 if (keySelector == null)
2498 throw new ArgumentNullException ("keySelector");
2499 if (elementSelector == null)
2500 throw new ArgumentNullException ("elementSelector");
2502 var dict = new Dictionary<TKey, TElement> (comparer);
2503 foreach (TSource e in source) {
2504 dict.Add (keySelector (e), elementSelector (e));
2512 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2515 throw new ArgumentNullException ("source");
2517 return new List<TSource> (source);
2523 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2525 return ToLookup<TSource, TKey> (source, keySelector, null);
2529 public static Lookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2530 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2532 if (source == null || keySelector == null)
2533 throw new ArgumentNullException ();
2535 var dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2536 foreach (TSource element in source) {
2537 TKey key = keySelector (element);
2539 throw new ArgumentNullException ();
2540 if (!dictionary.ContainsKey (key))
2541 dictionary.Add (key, new List<TSource> ());
2542 dictionary [key].Add (element);
2544 return new Lookup<TKey, TSource> (dictionary);
2548 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2549 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2551 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2555 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2556 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2558 if (source == null || keySelector == null || elementSelector == null)
2559 throw new ArgumentNullException ();
2561 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2562 foreach (TSource element in source) {
2563 TKey key = keySelector (element);
2565 throw new ArgumentNullException ();
2566 if (!dictionary.ContainsKey (key))
2567 dictionary.Add (key, new List<TElement> ());
2568 dictionary [key].Add (elementSelector (element));
2570 return new Lookup<TKey, TElement> (dictionary);
2577 public static IEnumerable<T> ToSequence<T> (this IEnumerable<T> source)
2579 return (IEnumerable<T>) source;
2586 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2588 return first.Union (second, null);
2591 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2593 if (first == null || second == null)
2594 throw new ArgumentNullException ();
2596 if (comparer == null)
2597 comparer = EqualityComparer<TSource>.Default;
2599 var items = new List<TSource> (); // TODO: use a HashSet here
2600 foreach (var element in first) {
2601 if (! items.Contains (element, comparer)) {
2602 items.Add (element);
2603 yield return element;
2607 foreach (var element in second) {
2608 if (! items.Contains (element, comparer)) {
2609 items.Add (element);
2610 yield return element;
2619 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2620 Func<TSource, bool> predicate)
2622 if (source == null || predicate == null)
2623 throw new ArgumentNullException ();
2625 foreach (TSource element in source)
2626 if (predicate (element))
2627 yield return element;
2631 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source,
2632 Func<TSource, int, bool> predicate)
2634 if (source == null || predicate == null)
2635 throw new ArgumentNullException ();
2638 foreach (TSource element in source) {
2639 if (predicate (element, counter))
2640 yield return element;
2647 // These methods are not included in the
2648 // .NET Standard Query Operators Specification,
2649 // but they provide additional useful commands
2653 static bool Equals<T> (T first, T second)
2655 // Mostly, values in Enumerable<T>
2656 // sequences need to be compared using
2657 // Equals and GetHashCode
2659 if (first == null || second == null)
2660 return (first == null && second == null);
2662 return ((first.Equals (second) ||
2663 first.GetHashCode () == second.GetHashCode ()));
2670 static int IndexOf<T> (this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2672 if (comparer == null)
2673 comparer = EqualityComparer<T>.Default;
2676 foreach (T element in source) {
2677 if (comparer.Equals (element, item))
2681 // The item was not found
2685 static int IndexOf<T> (this IEnumerable<T> source, T item)
2687 return IndexOf<T> (source, item, null);
2691 #region ToReadOnlyCollection
2692 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (IEnumerable<TSource> source)
2695 return new ReadOnlyCollection<TSource> (new List<TSource> ());
2697 if (typeof (ReadOnlyCollection<TSource>).IsInstanceOfType (source))
2698 return source as ReadOnlyCollection<TSource>;
2700 return new ReadOnlyCollection<TSource> (ToArray<TSource> (source));