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)
37 if (source == null || func == null)
38 throw new ArgumentNullException();
41 TSource folded = default(TSource);
43 foreach (TSource element in source)
48 folded = func(folded, element);
52 throw new InvalidOperationException();
58 public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source,
59 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
61 if (source == null || func == null)
62 throw new ArgumentNullException();
64 TAccumulate folded = seed;
65 foreach (TSource element in source)
66 folded = func(folded, element);
71 public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
74 throw new ArgumentNullException("source");
76 throw new ArgumentNullException("func");
77 if (resultSelector == null)
78 throw new ArgumentNullException("resultSelector");
80 TAccumulate result = seed;
81 foreach (TSource e in source)
82 result = func(result, e);
83 return resultSelector(result);
88 public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
90 if (source == null || predicate == null)
91 throw new ArgumentNullException();
93 foreach (TSource element in source)
94 if (!predicate(element))
101 public static bool Any<TSource>(this IEnumerable<TSource> source)
104 throw new ArgumentNullException();
106 foreach (TSource element in source)
112 public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
114 if (source == null || predicate == null)
115 throw new ArgumentNullException();
117 foreach (TSource element in source)
118 if (predicate(element))
125 public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
132 public static double Average(this IEnumerable<int> source)
135 throw new ArgumentNullException();
139 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)
162 if (element.HasValue)
165 sum += element.Value;
169 return (onlyNull ? null : (double?)sum / (double?)counter);
173 public static double Average(this IEnumerable<long> source)
176 throw new ArgumentNullException();
180 foreach (long element in source)
187 throw new InvalidOperationException();
189 return (double)sum / (double)counter;
193 public static double? Average(this IEnumerable<long?> source)
196 throw new ArgumentNullException();
198 bool onlyNull = true;
201 foreach (long? element in source)
203 if (element.HasValue)
206 sum += element.Value;
210 return (onlyNull ? null : (double?)sum / (double?)counter);
214 public static double Average(this IEnumerable<double> source)
217 throw new ArgumentNullException();
221 foreach (double element in source)
228 throw new InvalidOperationException();
230 return sum / counter;
234 public static double? Average(this IEnumerable<double?> source)
237 throw new ArgumentNullException();
239 bool onlyNull = true;
242 foreach (double? element in source)
244 if (element.HasValue)
247 sum += element.Value;
251 return (onlyNull ? null : (double?)(sum / counter));
255 public static decimal Average(this IEnumerable<decimal> source)
258 throw new ArgumentNullException();
262 foreach (decimal element in source)
269 throw new InvalidOperationException();
271 return sum / counter;
275 public static decimal? Average(this IEnumerable<decimal?> source)
278 throw new ArgumentNullException();
280 bool onlyNull = true;
283 foreach (decimal? element in source)
285 if (element.HasValue)
288 sum += element.Value;
292 return (onlyNull ? null : (decimal?)(sum / counter));
296 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
298 if (source == null || selector == null)
299 throw new ArgumentNullException();
303 foreach (TSource item in source)
305 sum += selector(item);
310 throw new InvalidOperationException();
312 return (double)sum / (double)counter;
316 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
318 if (source == null || selector == null)
319 throw new ArgumentNullException();
321 bool onlyNull = true;
324 foreach (TSource item in source)
326 int? element = selector(item);
327 if (element.HasValue)
330 sum += element.Value;
334 return (onlyNull ? null : (double?)sum / (double?)counter);
338 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
340 if (source == null || selector == null)
341 throw new ArgumentNullException();
345 foreach (TSource item in source)
347 sum += selector(item);
352 throw new InvalidOperationException();
354 return (double)sum / (double)counter;
358 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
360 if (source == null || selector == null)
361 throw new ArgumentNullException();
363 bool onlyNull = true;
366 foreach (TSource item in source)
368 long? element = selector(item);
369 if (element.HasValue)
372 sum += element.Value;
376 return (onlyNull ? null : (double?)sum / (double?)counter);
380 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
382 if (source == null || selector == null)
383 throw new ArgumentNullException();
387 foreach (TSource item in source)
389 sum += selector(item);
394 throw new InvalidOperationException();
396 return sum / counter;
400 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
402 if (source == null || selector == null)
403 throw new ArgumentNullException();
405 bool onlyNull = true;
408 foreach (TSource item in source)
410 double? element = selector(item);
411 if (element.HasValue)
414 sum += element.Value;
418 return (onlyNull ? null : (double?)(sum / counter));
422 public static decimal Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
424 if (source == null || selector == null)
425 throw new ArgumentNullException();
429 foreach (TSource item in source)
431 sum += selector(item);
436 throw new InvalidOperationException();
438 return sum / counter;
442 public static decimal? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
444 if (source == null || selector == null)
445 throw new ArgumentNullException();
447 bool onlyNull = true;
450 foreach (TSource item in source)
452 decimal? element = selector(item);
453 if (element.HasValue)
456 sum += element.Value;
460 return (onlyNull ? null : (decimal?)(sum / counter));
465 public static IEnumerable<TSource> Cast<TSource>(this IEnumerable source)
468 throw new ArgumentNullException();
470 foreach (object element in source)
471 yield return (TSource)element;
476 public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
478 if (first == null || second == null)
479 throw new ArgumentNullException();
481 foreach (TSource element in first)
482 yield return element;
483 foreach (TSource element in second)
484 yield return element;
491 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value)
493 if (source is ICollection<TSource>)
495 ICollection<TSource> collection = (ICollection<TSource>)source;
496 return collection.Contains(value);
499 return Contains<TSource>(source, value, null);
503 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
506 throw new ArgumentNullException("source");
508 if (comparer == null)
509 comparer = EqualityComparer<TSource>.Default;
512 foreach (TSource e in source)
514 if (comparer.Equals(e, value))
523 public static int Count<TSource>(this IEnumerable<TSource> source)
526 throw new ArgumentNullException();
528 if (source is ICollection<TSource>)
529 return ((ICollection<TSource>)source).Count;
533 foreach (TSource element in source)
540 public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> selector)
542 if (source == null || selector == null)
543 throw new ArgumentNullException();
546 foreach (TSource element in source)
547 if (selector(element))
554 #region DefaultIfEmpty
556 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source)
559 throw new ArgumentNullException();
562 foreach (TSource item in source)
569 yield return default(TSource);
573 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
576 throw new ArgumentNullException();
579 foreach (TSource item in source)
586 yield return defaultValue;
593 public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source)
595 return Distinct<TSource>(source, null);
598 public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
601 throw new ArgumentNullException();
603 if (comparer == null)
604 comparer = EqualityComparer<TSource>.Default;
606 List<TSource> items = new List<TSource>();
607 foreach (TSource element in source)
609 if (!Contains (items, element, comparer))
612 yield return element;
620 public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
623 throw new ArgumentNullException();
625 throw new ArgumentOutOfRangeException();
627 if (source is IList<TSource>)
628 return ((IList<TSource>)source)[index];
632 foreach (TSource element in source)
634 if (counter == index)
638 throw new ArgumentOutOfRangeException();
644 #region ElementAtOrDefault
646 public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
649 throw new ArgumentNullException();
651 return default(TSource);
653 if (source is IList<TSource>)
655 if (((IList<TSource>)source).Count >= index)
656 return default(TSource);
658 return ((IList<TSource>)source)[index];
663 foreach (TSource element in source)
665 if (counter == index)
669 return default(TSource);
676 public static IEnumerable<TResult> Empty<TResult>()
678 return new List<TResult>();
684 public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
686 return Except(first, second, null);
689 public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
691 if (first == null || second == null)
692 throw new ArgumentNullException();
694 if (comparer == null)
695 comparer = EqualityComparer<TSource>.Default;
697 List<TSource> items = new List<TSource>(Distinct(first));
698 foreach (TSource element in second)
700 int index = IndexOf(items, element, comparer);
704 items.RemoveAt(index);
706 foreach (TSource item in items)
714 public static TSource First<TSource>(this IEnumerable<TSource> source)
717 throw new ArgumentNullException();
719 foreach (TSource element in source)
722 throw new InvalidOperationException();
726 public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
728 if (source == null || predicate == null)
729 throw new ArgumentNullException();
731 foreach (TSource element in source)
733 if (predicate(element))
737 throw new InvalidOperationException();
742 #region FirstOrDefault
744 public static T FirstOrDefault<T>(this IEnumerable<T> source)
747 throw new ArgumentNullException();
749 foreach (T element in source)
756 public static T FirstOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate)
758 if (source == null || predicate == null)
759 throw new ArgumentNullException();
761 foreach (T element in source)
763 if (predicate(element))
774 private static List<T> ContainsGroup<K, T>(
775 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
777 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
778 foreach (KeyValuePair<K, List<T>> value in items)
780 if (comparerInUse.Equals(value.Key, key))
787 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source,
788 Func<TSource, TKey> keySelector)
790 return GroupBy<TSource, TKey>(source, keySelector, null);
794 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source,
795 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
797 if (source == null || keySelector == null)
798 throw new ArgumentNullException();
800 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>>();
801 List<TSource> nullList = new List<TSource>();
803 int nullCounter = -1;
805 foreach (TSource element in source)
807 TKey key = keySelector(element);
810 nullList.Add(element);
811 if (nullCounter == -1)
813 nullCounter = counter;
819 List<TSource> group = ContainsGroup<TKey, TSource>(groups, key, comparer);
822 group = new List<TSource>();
823 groups.Add(key, group);
831 foreach (KeyValuePair<TKey, List<TSource>> group in groups)
833 if (counter == nullCounter)
835 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource>(default(TKey), nullList);
836 yield return nullGroup;
839 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource>(group.Key, group.Value);
840 yield return grouping;
846 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source,
847 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
849 return GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
853 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source,
854 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
856 if (source == null || keySelector == null || elementSelector == null)
857 throw new ArgumentNullException();
859 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>>();
860 List<TElement> nullList = new List<TElement>();
862 int nullCounter = -1;
864 foreach (TSource item in source)
866 TKey key = keySelector(item);
867 TElement element = elementSelector(item);
870 nullList.Add(element);
871 if (nullCounter == -1)
873 nullCounter = counter;
879 List<TElement> group = ContainsGroup<TKey, TElement>(groups, key, comparer);
882 group = new List<TElement>();
883 groups.Add(key, group);
891 foreach (KeyValuePair<TKey, List<TElement>> group in groups)
893 if (counter == nullCounter)
895 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement>(default(TKey), nullList);
896 yield return nullGroup;
899 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement>(group.Key, group.Value);
900 yield return grouping;
909 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
910 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
911 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
913 return GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
916 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
917 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
918 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
919 IEqualityComparer<TKey> comparer)
921 if (outer == null || inner == null || outerKeySelector == null ||
922 innerKeySelector == null || resultSelector == null)
923 throw new ArgumentNullException();
925 if (comparer == null)
926 comparer = EqualityComparer<TKey>.Default;
928 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);
929 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
930 foreach (U element in inner)
932 K innerKey = innerKeySelector (element);
933 if (!innerKeys.ContainsKey (innerKey))
934 innerKeys.Add (innerKey, new List<U> ());
935 innerKeys[innerKey].Add (element);
938 foreach (TOuter element in outer)
940 TKey outerKey = outerKeySelector(element);
941 if (innerKeys.Contains(outerKey))
942 yield return resultSelector(element, innerKeys[outerKey]);
951 public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
953 if (first == null || second == null)
954 throw new ArgumentNullException();
956 List<TSource> items = new List<TSource>(Distinct(first));
957 bool[] marked = new bool[items.Count];
958 for (int i = 0; i < marked.Length; i++)
961 foreach (TSource element in second)
963 int index = IndexOf(items, element);
965 marked[index] = true;
967 for (int i = 0; i < marked.Length; i++)
970 yield return items[i];
978 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
979 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
980 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
982 if (outer == null || inner == null || outerKeySelector == null ||
983 innerKeySelector == null || resultSelector == null)
984 throw new ArgumentNullException();
986 if (comparer == null)
987 comparer = EqualityComparer<TKey>.Default;
989 Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);
990 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
991 foreach (U element in inner)
993 K innerKey = innerKeySelector (element);
994 if (!innerKeys.ContainsKey (innerKey))
995 innerKeys.Add (innerKey, new List<U> ());
996 innerKeys[innerKey].Add (element);
999 foreach (TOuter element in outer)
1001 TKey outerKey = outerKeySelector(element);
1002 if (innerKeys.Contains(outerKey))
1004 foreach (TInner innerElement in innerKeys[outerKey])
1005 yield return resultSelector(element, innerElement);
1010 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
1011 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
1012 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
1014 return Join<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector);
1020 public static TSource Last<TSource>(this IEnumerable<TSource> source)
1023 throw new ArgumentNullException();
1025 bool noElements = true;
1026 TSource lastElement = default(TSource);
1027 foreach (TSource element in source)
1029 if (noElements) noElements = false;
1030 lastElement = element;
1036 throw new InvalidOperationException();
1039 public static TSource Last<TSource>(this IEnumerable<TSource> source,
1040 Func<TSource, bool> predicate)
1042 if (source == null || predicate == null)
1043 throw new ArgumentNullException();
1045 bool noElements = true;
1046 TSource lastElement = default(TSource);
1047 foreach (TSource element in source)
1049 if (predicate(element))
1051 if (noElements) noElements = false;
1052 lastElement = element;
1059 throw new InvalidOperationException();
1064 #region LastOrDefault
1066 public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)
1069 throw new ArgumentNullException();
1071 TSource lastElement = default(TSource);
1072 foreach (TSource element in source)
1073 lastElement = element;
1078 public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source,
1079 Func<TSource, bool> predicate)
1081 if (source == null || predicate == null)
1082 throw new ArgumentNullException();
1084 TSource lastElement = default(TSource);
1085 foreach (TSource element in source)
1087 if (predicate(element))
1088 lastElement = element;
1097 public static long LongCount<TSource>(this IEnumerable<TSource> source)
1100 throw new ArgumentNullException();
1103 foreach (TSource element in source)
1109 public static long LongCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> selector)
1111 if (source == null || selector == null)
1112 throw new ArgumentNullException();
1115 foreach (TSource element in source)
1116 if (selector(element))
1126 public static int Max(this IEnumerable<int> source)
1129 throw new ArgumentNullException();
1131 int maximum = int.MinValue;
1133 foreach (int element in source)
1135 if (element > maximum)
1141 throw new InvalidOperationException();
1147 public static int? Max(this IEnumerable<int?> source)
1150 throw new ArgumentNullException();
1152 bool onlyNull = true;
1153 int? maximum = int.MinValue;
1154 foreach (int? element in source)
1156 if (element.HasValue)
1159 if (element > maximum)
1163 return (onlyNull ? null : maximum);
1167 public static long Max(this IEnumerable<long> source)
1170 throw new ArgumentNullException();
1172 long maximum = long.MinValue;
1174 foreach (long element in source)
1176 if (element > maximum)
1182 throw new InvalidOperationException();
1188 public static long? Max(this IEnumerable<long?> source)
1191 throw new ArgumentNullException();
1193 bool onlyNull = true;
1194 long? maximum = long.MinValue;
1195 foreach (long? element in source)
1197 if (element.HasValue)
1200 if (element > maximum)
1204 return (onlyNull ? null : maximum);
1208 public static double Max(this IEnumerable<double> source)
1211 throw new ArgumentNullException();
1213 double maximum = double.MinValue;
1215 foreach (double element in source)
1217 if (element > maximum)
1223 throw new InvalidOperationException();
1229 public static double? Max(this IEnumerable<double?> source)
1232 throw new ArgumentNullException();
1234 bool onlyNull = true;
1235 double? maximum = double.MinValue;
1236 foreach (double? element in source)
1238 if (element.HasValue)
1241 if (element > maximum)
1245 return (onlyNull ? null : maximum);
1249 public static decimal Max(this IEnumerable<decimal> source)
1252 throw new ArgumentNullException();
1254 decimal maximum = decimal.MinValue;
1256 foreach (decimal element in source)
1258 if (element > maximum)
1264 throw new InvalidOperationException();
1270 public static decimal? Max(this IEnumerable<decimal?> source)
1273 throw new ArgumentNullException();
1275 bool onlyNull = true;
1276 decimal? maximum = decimal.MinValue;
1277 foreach (decimal? element in source)
1279 if (element.HasValue)
1282 if (element > maximum)
1286 return (onlyNull ? null : maximum);
1290 public static T Max<T>(this IEnumerable<T> source)
1293 throw new ArgumentNullException();
1295 bool notAssigned = true;
1296 T maximum = default(T);
1298 foreach (T element in source)
1303 notAssigned = false;
1308 if (element is IComparable<T>)
1309 comparison = ((IComparable<T>)element).CompareTo(maximum);
1310 else if (element is System.IComparable)
1311 comparison = ((System.IComparable)element).CompareTo(maximum);
1313 throw new ArgumentNullException();
1322 throw new InvalidOperationException();
1328 public static int Max<T>(this IEnumerable<T> source,
1329 Func<T, int> selector)
1331 if (source == null || selector == null)
1332 throw new ArgumentNullException();
1334 int maximum = int.MinValue;
1336 foreach (T item in source)
1338 int element = selector(item);
1339 if (element > maximum)
1345 throw new InvalidOperationException();
1351 public static int? Max<T>(this IEnumerable<T> source,
1352 Func<T, int?> selector)
1354 if (source == null || selector == null)
1355 throw new ArgumentNullException();
1357 bool onlyNull = true;
1358 int? maximum = int.MinValue;
1359 foreach (T item in source)
1361 int? element = selector(item);
1362 if (element.HasValue)
1365 if (element > maximum)
1369 return (onlyNull ? null : maximum);
1373 public static long Max<TSource>(this IEnumerable<TSource> source,
1374 Func<TSource, long> selector)
1376 if (source == null || selector == null)
1377 throw new ArgumentNullException();
1379 long maximum = long.MinValue;
1381 foreach (TSource item in source)
1383 long element = selector(item);
1384 if (element > maximum)
1390 throw new InvalidOperationException();
1396 public static long? Max<TSource>(this IEnumerable<TSource> source,
1397 Func<TSource, long?> selector)
1399 if (source == null || selector == null)
1400 throw new ArgumentNullException();
1402 bool onlyNull = true;
1403 long? maximum = long.MinValue;
1404 foreach (TSource item in source)
1406 long? element = selector(item);
1407 if (element.HasValue)
1410 if (element > maximum)
1414 return (onlyNull ? null : maximum);
1418 public static double Max<TSource>(this IEnumerable<TSource> source,
1419 Func<TSource, double> selector)
1421 if (source == null || selector == null)
1422 throw new ArgumentNullException();
1424 double maximum = double.MinValue;
1426 foreach (TSource item in source)
1428 double element = selector(item);
1429 if (element > maximum)
1435 throw new InvalidOperationException();
1441 public static double? Max<TSource>(this IEnumerable<TSource> source,
1442 Func<TSource, double?> selector)
1444 if (source == null || selector == null)
1445 throw new ArgumentNullException();
1447 bool onlyNull = true;
1448 double? maximum = double.MinValue;
1449 foreach (TSource item in source)
1451 double? element = selector(item);
1452 if (element.HasValue)
1455 if (element > maximum)
1459 return (onlyNull ? null : maximum);
1463 public static decimal Max<TSource>(this IEnumerable<TSource> source,
1464 Func<TSource, decimal> selector)
1466 if (source == null || selector == null)
1467 throw new ArgumentNullException();
1469 decimal maximum = decimal.MinValue;
1471 foreach (TSource item in source)
1473 decimal element = selector(item);
1474 if (element > maximum)
1480 throw new InvalidOperationException();
1486 public static decimal? Max<TSource>(this IEnumerable<TSource> source,
1487 Func<TSource, decimal?> selector)
1489 if (source == null || selector == null)
1490 throw new ArgumentNullException();
1492 bool onlyNull = true;
1493 decimal? maximum = decimal.MinValue;
1494 foreach (TSource item in source)
1496 decimal? element = selector(item);
1497 if (element.HasValue)
1500 if (element > maximum)
1504 return (onlyNull ? null : maximum);
1508 public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source,
1509 Func<TSource, TResult> selector)
1511 if (source == null || selector == null)
1512 throw new ArgumentNullException();
1514 bool notAssigned = true;
1515 TResult maximum = default(TResult);
1517 foreach (TSource item in source)
1519 TResult element = selector(item);
1523 notAssigned = false;
1528 if (element is IComparable<TResult>)
1529 comparison = ((IComparable<TResult>)element).CompareTo(maximum);
1530 else if (element is System.IComparable)
1531 comparison = ((System.IComparable)element).CompareTo(maximum);
1533 throw new ArgumentNullException();
1542 throw new InvalidOperationException();
1551 public static int Min(this IEnumerable<int> source)
1554 throw new ArgumentNullException();
1556 int minimum = int.MaxValue;
1558 foreach (int element in source)
1560 if (element < minimum)
1566 throw new InvalidOperationException();
1572 public static int? Min(this IEnumerable<int?> source)
1575 throw new ArgumentNullException();
1577 bool onlyNull = true;
1578 int? minimum = int.MaxValue;
1579 foreach (int? element in source)
1581 if (element.HasValue)
1584 if (element < minimum)
1588 return (onlyNull ? null : minimum);
1591 public static long Min(this IEnumerable<long> source)
1594 throw new ArgumentNullException();
1596 long minimum = long.MaxValue;
1598 foreach (long element in source)
1600 if (element < minimum)
1606 throw new InvalidOperationException();
1612 public static long? Min(this IEnumerable<long?> source)
1615 throw new ArgumentNullException();
1617 bool onlyNull = true;
1618 long? minimum = long.MaxValue;
1619 foreach (long? element in source)
1621 if (element.HasValue)
1624 if (element < minimum)
1628 return (onlyNull ? null : minimum);
1632 public static double Min(this IEnumerable<double> source)
1635 throw new ArgumentNullException();
1637 double minimum = double.MaxValue;
1639 foreach (double element in source)
1641 if (element < minimum)
1647 throw new InvalidOperationException();
1653 public static double? Min(this IEnumerable<double?> source)
1656 throw new ArgumentNullException();
1658 bool onlyNull = true;
1659 double? minimum = double.MaxValue;
1660 foreach (double? element in source)
1662 if (element.HasValue)
1665 if (element < minimum)
1669 return (onlyNull ? null : minimum);
1673 public static decimal Min(this IEnumerable<decimal> source)
1676 throw new ArgumentNullException();
1678 decimal minimum = decimal.MaxValue;
1680 foreach (decimal element in source)
1682 if (element < minimum)
1688 throw new InvalidOperationException();
1694 public static decimal? Min(this IEnumerable<decimal?> source)
1697 throw new ArgumentNullException();
1699 bool onlyNull = true;
1700 decimal? minimum = decimal.MaxValue;
1701 foreach (decimal? element in source)
1703 if (element.HasValue)
1706 if (element < minimum)
1710 return (onlyNull ? null : minimum);
1714 public static TSource Min<TSource>(this IEnumerable<TSource> source)
1717 throw new ArgumentNullException();
1719 bool notAssigned = true;
1720 TSource minimum = default(TSource);
1722 foreach (TSource element in source)
1727 notAssigned = false;
1732 if (element is IComparable<TSource>)
1733 comparison = ((IComparable<TSource>)element).CompareTo(minimum);
1734 else if (element is System.IComparable)
1735 comparison = ((System.IComparable)element).CompareTo(minimum);
1737 throw new ArgumentNullException();
1746 throw new InvalidOperationException();
1752 public static int Min<TSource>(this IEnumerable<TSource> source,
1753 Func<TSource, int> selector)
1755 if (source == null || selector == null)
1756 throw new ArgumentNullException();
1758 int minimum = int.MaxValue;
1760 foreach (TSource item in source)
1762 int element = selector(item);
1763 if (element < minimum)
1769 throw new InvalidOperationException();
1775 public static int? Min<TSource>(this IEnumerable<TSource> source,
1776 Func<TSource, int?> selector)
1778 if (source == null || selector == null)
1779 throw new ArgumentNullException();
1781 bool onlyNull = true;
1782 int? minimum = int.MaxValue;
1783 foreach (TSource item in source)
1785 int? element = selector(item);
1786 if (element.HasValue)
1789 if (element < minimum)
1793 return (onlyNull ? null : minimum);
1797 public static long Min<TSource>(this IEnumerable<TSource> source,
1798 Func<TSource, long> selector)
1800 if (source == null || selector == null)
1801 throw new ArgumentNullException();
1803 long minimum = long.MaxValue;
1805 foreach (TSource item in source)
1807 long element = selector(item);
1808 if (element < minimum)
1814 throw new InvalidOperationException();
1820 public static long? Min<TSource>(this IEnumerable<TSource> source,
1821 Func<TSource, long?> selector)
1823 if (source == null || selector == null)
1824 throw new ArgumentNullException();
1826 bool onlyNull = true;
1827 long? minimum = long.MaxValue;
1828 foreach (TSource item in source)
1830 long? element = selector(item);
1831 if (element.HasValue)
1834 if (element < minimum)
1838 return (onlyNull ? null : minimum);
1842 public static double Min<TSource>(this IEnumerable<TSource> source,
1843 Func<TSource, double> selector)
1845 if (source == null || selector == null)
1846 throw new ArgumentNullException();
1848 double minimum = double.MaxValue;
1850 foreach (TSource item in source)
1852 double element = selector(item);
1853 if (element < minimum)
1859 throw new InvalidOperationException();
1865 public static double? Min<TSource>(this IEnumerable<TSource> source,
1866 Func<TSource, double?> selector)
1868 if (source == null || selector == null)
1869 throw new ArgumentNullException();
1871 bool onlyNull = true;
1872 double? minimum = double.MaxValue;
1873 foreach (TSource item in source)
1875 double? element = selector(item);
1876 if (element.HasValue)
1879 if (element < minimum)
1883 return (onlyNull ? null : minimum);
1887 public static decimal Min<TSource>(this IEnumerable<TSource> source,
1888 Func<TSource, decimal> selector)
1890 if (source == null || selector == null)
1891 throw new ArgumentNullException();
1893 decimal minimum = decimal.MaxValue;
1895 foreach (TSource item in source)
1897 decimal element = selector(item);
1898 if (element < minimum)
1904 throw new InvalidOperationException();
1910 public static decimal? Min<TSource>(this IEnumerable<TSource> source,
1911 Func<TSource, decimal?> selector)
1913 if (source == null || selector == null)
1914 throw new ArgumentNullException();
1916 bool onlyNull = true;
1917 decimal? minimum = decimal.MaxValue;
1918 foreach (TSource item in source)
1920 decimal? element = selector(item);
1921 if (element.HasValue)
1924 if (element < minimum)
1928 return (onlyNull ? null : minimum);
1932 public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source,
1933 Func<TSource, TResult> selector)
1935 if (source == null || selector == null)
1936 throw new ArgumentNullException();
1938 bool notAssigned = true;
1939 TResult minimum = default(TResult);
1941 foreach (TSource item in source)
1943 TResult element = selector(item);
1947 notAssigned = false;
1952 if (element is IComparable<TResult>)
1953 comparison = ((IComparable<TResult>)element).CompareTo(minimum);
1954 else if (element is System.IComparable)
1955 comparison = ((System.IComparable)element).CompareTo(minimum);
1957 throw new ArgumentNullException();
1966 throw new InvalidOperationException();
1975 public static IEnumerable<TSource> OfType<TSource>(this IEnumerable source)
1978 throw new ArgumentNullException();
1980 foreach (object element in source)
1981 if (element is TSource)
1982 yield return (TSource)element;
1989 public static OrderedSequence<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,
1990 Func<TSource, TKey> keySelector)
1992 return OrderBy<TSource, TKey>(source, keySelector, null);
1996 public static OrderedSequence<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,
1997 Func<TSource, TKey> keySelector,
1998 IComparer<TKey> comparer)
2000 if (source == null || keySelector == null)
2001 throw new ArgumentNullException();
2003 return new InternalOrderedSequence<TSource, TKey>(
2004 source, keySelector, (comparer ?? Comparer<TKey>.Default), false, null);
2009 #region OrderByDescending
2011 public static OrderedSequence<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source,
2012 Func<TSource, TKey> keySelector)
2014 return OrderByDescending<TSource, TKey>(source, keySelector, null);
2018 public static OrderedSequence<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source,
2019 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2021 if (source == null || keySelector == null)
2022 throw new ArgumentNullException();
2024 return new InternalOrderedSequence<TSource, TKey>(
2025 source, keySelector, (comparer ?? Comparer<TKey>.Default), true, null);
2032 public static IEnumerable<int> Range(int start, int count)
2034 if (count < 0 || (start + count - 1) > int.MaxValue)
2035 throw new ArgumentOutOfRangeException();
2037 for (int i = start; i < (start + count - 1); i++)
2045 public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
2048 throw new ArgumentOutOfRangeException();
2050 for (int i = 0; i < count; i++)
2051 yield return element;
2059 public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source)
2062 throw new ArgumentNullException();
2064 List<TSource> list = new List<TSource>(source);
2073 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,
2074 Func<TSource, TResult> selector)
2076 if (source == null || selector == null)
2077 throw new ArgumentNullException();
2079 foreach (TSource element in source)
2080 yield return selector(element);
2084 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,
2085 Func<TSource, int, TResult> selector)
2087 if (source == null || selector == null)
2088 throw new ArgumentNullException();
2091 foreach (TSource element in source)
2093 yield return selector(element, counter);
2102 public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source,
2103 Func<TSource, IEnumerable<TResult>> selector)
2105 if (source == null || selector == null)
2106 throw new ArgumentNullException();
2108 foreach (TSource element in source)
2109 foreach (TResult item in selector(element))
2114 public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source,
2115 Func<TSource, int, IEnumerable<TResult>> selector)
2117 if (source == null || selector == null)
2118 throw new ArgumentNullException();
2121 foreach (TSource element in source)
2123 foreach (TResult item in selector(element, counter))
2133 public static TSource Single<TSource>(this IEnumerable<TSource> source)
2136 throw new ArgumentNullException();
2138 bool otherElement = false;
2139 TSource singleElement = default(TSource);
2140 foreach (TSource element in source)
2142 if (otherElement) throw new InvalidOperationException();
2143 if (!otherElement) otherElement = true;
2144 singleElement = element;
2148 return singleElement;
2150 throw new InvalidOperationException();
2154 public static TSource Single<TSource>(this IEnumerable<TSource> source,
2155 Func<TSource, bool> predicate)
2157 if (source == null || predicate == null)
2158 throw new ArgumentNullException();
2160 bool otherElement = false;
2161 TSource singleElement = default(TSource);
2162 foreach (TSource element in source)
2164 if (predicate(element))
2166 if (otherElement) throw new InvalidOperationException();
2167 if (!otherElement) otherElement = true;
2168 singleElement = element;
2173 return singleElement;
2175 throw new InvalidOperationException();
2180 #region SingleOrDefault
2182 public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
2185 throw new ArgumentNullException();
2187 bool otherElement = false;
2188 TSource singleElement = default(TSource);
2189 foreach (TSource element in source)
2191 if (otherElement) throw new InvalidOperationException();
2192 if (!otherElement) otherElement = true;
2193 singleElement = element;
2196 return singleElement;
2200 public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source,
2201 Func<TSource, bool> predicate)
2203 if (source == null || predicate == null)
2204 throw new ArgumentNullException();
2206 bool otherElement = false;
2207 TSource singleElement = default(TSource);
2208 foreach (TSource element in source)
2210 if (predicate(element))
2212 if (otherElement) throw new InvalidOperationException();
2213 if (!otherElement) otherElement = true;
2214 singleElement = element;
2218 return singleElement;
2224 public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)
2227 throw new NotSupportedException();
2230 foreach (TSource e in source)
2242 public static IEnumerable<T> SkipWhile<T>(
2243 IEnumerable<T> source,
2244 Func<T, bool> predicate)
2246 if (source == null || predicate == null)
2247 throw new ArgumentNullException();
2251 foreach (T element in source)
2254 yield return element;
2256 if (!predicate(element))
2258 yield return element;
2265 public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source,
2266 Func<TSource, int, bool> predicate)
2268 if (source == null || predicate == null)
2269 throw new ArgumentNullException();
2274 foreach (TSource element in source)
2277 yield return element;
2279 if (!predicate(element, counter))
2281 yield return element;
2292 public static int Sum(this IEnumerable<int> source)
2295 throw new ArgumentNullException("source");
2298 foreach (int element in source)
2305 public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
2307 if (source == null || selector == null)
2308 throw new ArgumentNullException();
2311 foreach (TSource element in source)
2312 sum += selector(element);
2318 public static int? Sum(this IEnumerable<int?> source)
2321 throw new ArgumentNullException();
2324 foreach (int? element in source)
2325 if (element.HasValue)
2326 sum += element.Value;
2332 public static int? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)
2334 if (source == null || selector == null)
2335 throw new ArgumentNullException();
2338 foreach (TSource element in source)
2340 int? item = selector(element);
2349 public static long Sum(this IEnumerable<long> source)
2352 throw new ArgumentNullException();
2355 foreach (long element in source)
2362 public static long Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
2364 if (source == null || selector == null)
2365 throw new ArgumentNullException();
2368 foreach (TSource element in source)
2369 sum += selector(element);
2375 public static long? Sum(this IEnumerable<long?> source)
2378 throw new ArgumentNullException();
2381 foreach (long? element in source)
2382 if (element.HasValue)
2383 sum += element.Value;
2389 public static long? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)
2391 if (source == null || selector == null)
2392 throw new ArgumentNullException();
2395 foreach (TSource element in source)
2397 long? item = selector(element);
2406 public static double Sum(this IEnumerable<double> source)
2409 throw new ArgumentNullException();
2412 foreach (double element in source)
2419 public static double Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
2421 if (source == null || selector == null)
2422 throw new ArgumentNullException();
2425 foreach (TSource element in source)
2426 sum += selector(element);
2432 public static double? Sum(this IEnumerable<double?> source)
2435 throw new ArgumentNullException();
2438 foreach (double? element in source)
2439 if (element.HasValue)
2440 sum += element.Value;
2446 public static double? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)
2448 if (source == null || selector == null)
2449 throw new ArgumentNullException();
2452 foreach (TSource element in source)
2454 double? item = selector(element);
2463 public static decimal Sum(this IEnumerable<decimal> source)
2466 throw new ArgumentNullException();
2469 foreach (decimal element in source)
2476 public static decimal Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
2478 if (source == null || selector == null)
2479 throw new ArgumentNullException();
2482 foreach (TSource element in source)
2483 sum += selector(element);
2489 public static decimal? Sum(this IEnumerable<decimal?> source)
2492 throw new ArgumentNullException();
2495 foreach (decimal? element in source)
2496 if (element.HasValue)
2497 sum += element.Value;
2503 public static decimal? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2505 if (source == null || selector == null)
2506 throw new ArgumentNullException();
2509 foreach (TSource element in source)
2511 decimal? item = selector(element);
2522 public static IEnumerable<T> Take<T>(this IEnumerable<T> source, int count)
2525 throw new ArgumentNullException();
2532 foreach (T element in source)
2534 yield return element;
2536 if (counter == count)
2546 public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate)
2548 if (source == null || predicate == null)
2549 throw new ArgumentNullException();
2551 foreach (T element in source)
2553 if (predicate(element))
2554 yield return element;
2560 public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2562 if (source == null || predicate == null)
2563 throw new ArgumentNullException();
2566 foreach (TSource element in source)
2568 if (predicate(element, counter))
2569 yield return element;
2580 public static OrderedSequence<TSource> ThenBy<TSource, TKey>(this OrderedSequence<TSource> source, Func<TSource, TKey> keySelector)
2582 return ThenBy<TSource, TKey>(source, keySelector, null);
2586 public static OrderedSequence<TSource> ThenBy<TSource, TKey>(this OrderedSequence<TSource> source,
2587 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2589 if (source == null || keySelector == null)
2590 throw new ArgumentNullException();
2592 return new InternalOrderedSequence<TSource, TKey>(
2593 source, keySelector, (comparer ?? Comparer<TKey>.Default), false, source);
2598 #region ThenByDescending
2600 public static OrderedSequence<TSource> ThenByDescending<TSource, TKey>(this OrderedSequence<TSource> source,
2601 Func<TSource, TKey> keySelector)
2603 return ThenByDescending<TSource, TKey>(source, keySelector, null);
2607 public static OrderedSequence<TSource> ThenByDescending<TSource, TKey>(this OrderedSequence<TSource> source,
2608 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2610 if (source == null || keySelector == null)
2611 throw new ArgumentNullException();
2613 return new InternalOrderedSequence<TSource, TKey>(
2614 source, keySelector, (comparer ?? Comparer<TKey>.Default), true, source);
2620 public static T[] ToArray<T> (this IEnumerable<T> source)
2623 throw new ArgumentNullException ();
2625 List<T> list = new List<T> (source);
2626 return list.ToArray ();
2631 #region ToDictionary
2632 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2634 return ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
2638 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2641 throw new ArgumentNullException("source");
2642 if (keySelector == null)
2643 throw new ArgumentNullException("keySelector");
2644 if (elementSelector == null)
2645 throw new ArgumentNullException("elementSelector");
2647 Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement>(comparer);
2648 foreach (TSource e in source)
2650 dict.Add(keySelector(e), elementSelector(e));
2658 public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
2661 throw new ArgumentNullException("source");
2663 return new List<TSource>(source);
2669 public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2671 return ToLookup<TSource, TKey>(source, keySelector, null);
2675 public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source,
2676 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2678 if (source == null || keySelector == null)
2679 throw new ArgumentNullException();
2681 Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>>(comparer ?? EqualityComparer<TKey>.Default);
2682 foreach (TSource element in source)
2684 TKey key = keySelector(element);
2686 throw new ArgumentNullException();
2687 if (!dictionary.ContainsKey(key))
2688 dictionary.Add(key, new List<TSource>());
2689 dictionary[key].Add(element);
2691 return new Lookup<TKey, TSource>(dictionary);
2695 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source,
2696 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2698 return ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
2702 public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source,
2703 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2705 if (source == null || keySelector == null || elementSelector == null)
2706 throw new ArgumentNullException();
2708 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>>(comparer ?? EqualityComparer<TKey>.Default);
2709 foreach (TSource element in source)
2711 TKey key = keySelector(element);
2713 throw new ArgumentNullException();
2714 if (!dictionary.ContainsKey(key))
2715 dictionary.Add(key, new List<TElement>());
2716 dictionary[key].Add(elementSelector(element));
2718 return new Lookup<TKey, TElement>(dictionary);
2725 public static IEnumerable<T> ToSequence<T>(this IEnumerable<T> source)
2727 return (IEnumerable<T>)source;
2735 public static IEnumerable<T> Union<T>(this IEnumerable<T> first, IEnumerable<T> second)
2737 if (first == null || second == null)
2738 throw new ArgumentNullException();
2740 List<T> items = new List<T>();
2741 foreach (T element in first)
2743 if (IndexOf(items, element) == -1)
2746 yield return element;
2749 foreach (T element in second)
2751 if (IndexOf(items, element) == -1)
2754 yield return element;
2763 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
2764 Func<TSource, bool> predicate)
2766 if (source == null || predicate == null)
2767 throw new ArgumentNullException();
2769 foreach (TSource element in source)
2770 if (predicate(element))
2771 yield return element;
2775 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
2776 Func<TSource, int, bool> predicate)
2778 if (source == null || predicate == null)
2779 throw new ArgumentNullException();
2782 foreach (TSource element in source)
2784 if (predicate(element, counter))
2785 yield return element;
2792 // These methods are not included in the
2793 // .NET Standard Query Operators Specification,
2794 // but they provide additional useful commands
2798 private static bool Equals<T>(T first, T second)
2800 // Mostly, values in Enumerable<T>
2801 // sequences need to be compared using
2802 // Equals and GetHashCode
2804 if (first == null || second == null)
2805 return (first == null && second == null);
2807 return ((first.Equals(second) ||
2808 first.GetHashCode() == second.GetHashCode()));
2815 public static int IndexOf<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
2817 if (comparer == null)
2818 comparer = EqualityComparer<T>.Default;
2821 foreach (T element in source)
2823 if (comparer.Equals(element, item))
2827 // The item was not found
2831 public static int IndexOf<T>(this IEnumerable<T> source, T item)
2833 return IndexOf<T>(source, item, null);
2837 #region ToReadOnlyCollection
2838 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource>(IEnumerable<TSource> source)
2841 return new ReadOnlyCollection<TSource>(new List<TSource>());
2843 if (typeof(ReadOnlyCollection<TSource>).IsInstanceOfType(source))
2844 return source as ReadOnlyCollection<TSource>;
2846 return new ReadOnlyCollection<TSource>(ToArray<TSource>(source));