5 // Marek Safar (marek.safar@gmail.com)
6 // Antonello Provenzano <antonello@deveel.com>
7 // Alejandro Serrano "Serras" (trupill@yahoo.es)
8 // Jb Evain (jbevain@novell.com)
10 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 // precious: http://www.hookedonlinq.com
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Collections.ObjectModel;
41 public static class Enumerable
48 class PredicateOf<T> {
49 public static readonly Func<T, bool> Always = (t) => true;
54 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
56 Check.SourceAndFunc (source, func);
58 // custom foreach so that we can efficiently throw an exception
59 // if zero elements and treat the first element differently
60 using (var enumerator = source.GetEnumerator ()) {
61 if (!enumerator.MoveNext ())
62 throw new InvalidOperationException ("No elements in source list");
64 TSource folded = enumerator.Current;
65 while (enumerator.MoveNext ())
66 folded = func (folded, enumerator.Current);
71 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
72 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
74 Check.SourceAndFunc (source, func);
76 TAccumulate folded = seed;
77 foreach (TSource element in source)
78 folded = func (folded, element);
83 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
85 Check.SourceAndFunc (source, func);
86 if (resultSelector == null)
87 throw new ArgumentNullException ("resultSelector");
90 foreach (var e in source)
91 result = func (result, e);
93 return resultSelector (result);
100 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
102 Check.SourceAndPredicate (source, predicate);
104 foreach (var element in source)
105 if (!predicate (element))
115 public static bool Any<TSource> (this IEnumerable<TSource> source)
117 Check.Source (source);
119 using (var enumerator = source.GetEnumerator ())
120 return enumerator.MoveNext ();
123 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
125 Check.SourceAndPredicate (source, predicate);
127 foreach (TSource element in source)
128 if (predicate (element))
138 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
147 public static double Average (this IEnumerable<int> source)
149 return Average<int, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
152 public static double Average (this IEnumerable<long> source)
154 return Average<long, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
157 public static double Average (this IEnumerable<double> source)
159 return Average<double, double, double> (source, (a, b) => a + b, (a, b) => a / b);
162 public static float Average (this IEnumerable<float> source)
164 return Average<float, double, float> (source, (a, b) => a + b, (a, b) => (float) a / (float) b);
167 public static decimal Average (this IEnumerable<decimal> source)
169 return Average<decimal, decimal, decimal> (source, (a, b) => a + b, (a, b) => a / b);
172 static TResult Average<TElement, TAggregate, TResult> (this IEnumerable<TElement> source,
173 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
174 where TElement : struct
175 where TAggregate : struct
176 where TResult : struct
178 Check.Source (source);
180 var total = default (TAggregate);
182 foreach (var element in source) {
183 total = func (total, element);
188 throw new InvalidOperationException ();
190 return result (total, counter);
193 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
194 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
195 where TElement : struct
196 where TAggregate : struct
197 where TResult : struct
199 Check.Source (source);
201 var total = default (TAggregate);
203 foreach (var element in source) {
204 if (!element.HasValue)
207 total = func (total, element.Value);
214 return new TResult? (result (total, counter));
217 public static double? Average (this IEnumerable<int?> source)
219 Check.Source (source);
221 return source.AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
224 public static double? Average (this IEnumerable<long?> source)
226 Check.Source (source);
228 return source.AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => a / b);
231 public static double? Average (this IEnumerable<double?> source)
233 Check.Source (source);
235 return source.AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
238 public static decimal? Average (this IEnumerable<decimal?> source)
240 Check.Source (source);
242 return source.AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
245 public static float? Average (this IEnumerable<float?> source)
247 Check.Source (source);
249 return source.AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
252 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
254 Check.SourceAndSelector (source, selector);
256 return source.Select (selector).Average<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
259 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
261 Check.SourceAndSelector (source, selector);
263 return source.Select (selector).AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
266 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
268 Check.SourceAndSelector (source, selector);
270 return source.Select (selector).Average<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
273 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
275 Check.SourceAndSelector (source, selector);
277 return source.Select (selector).AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
280 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
282 Check.SourceAndSelector (source, selector);
284 return source.Select (selector).Average<double, double, double> ((a, b) => a + b, (a, b) => a / b);
287 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
289 Check.SourceAndSelector (source, selector);
291 return source.Select (selector).AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
294 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
296 Check.SourceAndSelector (source, selector);
298 return source.Select (selector).Average<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
301 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
303 Check.SourceAndSelector (source, selector);
305 return source.Select (selector).AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
308 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
310 Check.SourceAndSelector (source, selector);
312 return source.Select (selector).Average<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
315 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
317 Check.SourceAndSelector (source, selector);
319 return source.Select (selector).AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
326 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
328 Check.Source (source);
330 return CreateCastIterator<TResult> (source);
333 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
335 foreach (object element in source)
336 yield return (TResult) element;
343 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
345 Check.FirstAndSecond (first, second);
347 return CreateConcatIterator (first, second);
350 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
352 foreach (TSource element in first)
353 yield return element;
354 foreach (TSource element in second)
355 yield return element;
362 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
364 var collection = source as ICollection<TSource>;
365 if (collection != null)
366 return collection.Contains (value);
368 return Contains<TSource> (source, value, null);
371 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
373 Check.Source (source);
375 if (comparer == null)
376 comparer = EqualityComparer<TSource>.Default;
378 foreach (var element in source)
379 if (comparer.Equals (element, value))
388 public static int Count<TSource> (this IEnumerable<TSource> source)
390 Check.Source (source);
392 var collection = source as ICollection<TSource>;
393 if (collection != null)
394 return collection.Count;
397 using (var enumerator = source.GetEnumerator ())
398 while (enumerator.MoveNext ())
404 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
406 Check.SourceAndSelector (source, selector);
409 foreach (var element in source)
410 if (selector (element))
418 #region DefaultIfEmpty
420 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
422 return DefaultIfEmpty (source, default (TSource));
425 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
427 Check.Source (source);
429 return CreateDefaultIfEmptyIterator (source, defaultValue);
432 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
435 foreach (TSource item in source) {
441 yield return defaultValue;
448 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
450 return Distinct<TSource> (source, null);
453 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
455 Check.Source (source);
457 if (comparer == null)
458 comparer = EqualityComparer<TSource>.Default;
460 return CreateDistinctIterator (source, comparer);
463 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
465 var items = new HashSet<TSource> (comparer);
466 foreach (var element in source) {
467 if (! items.Contains (element)) {
469 yield return element;
478 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
482 foreach (var element in source) {
483 if (index == counter++)
487 if (fallback == Fallback.Throw)
488 throw new ArgumentOutOfRangeException ();
490 return default (TSource);
493 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
495 Check.Source (source);
498 throw new ArgumentOutOfRangeException ();
500 var list = source as IList<TSource>;
504 return source.ElementAt (index, Fallback.Throw);
509 #region ElementAtOrDefault
511 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
513 Check.Source (source);
516 return default (TSource);
518 var list = source as IList<TSource>;
520 return index < list.Count ? list [index] : default (TSource);
522 return source.ElementAt (index, Fallback.Default);
529 public static IEnumerable<TResult> Empty<TResult> ()
531 return new TResult [0];
538 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
540 return Except (first, second, null);
543 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
545 Check.FirstAndSecond (first, second);
547 if (comparer == null)
548 comparer = EqualityComparer<TSource>.Default;
550 return CreateExceptIterator (first, second, comparer);
553 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
555 var items = new HashSet<TSource> (second, comparer);
556 foreach (var element in first) {
557 if (!items.Contains (element, comparer))
558 yield return element;
566 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
568 foreach (var element in source)
569 if (predicate (element))
572 if (fallback == Fallback.Throw)
573 throw new InvalidOperationException ();
575 return default (TSource);
578 public static TSource First<TSource> (this IEnumerable<TSource> source)
580 Check.Source (source);
582 var list = source as IList<TSource>;
587 throw new InvalidOperationException ();
589 using (var enumerator = source.GetEnumerator ()) {
590 if (enumerator.MoveNext ())
591 return enumerator.Current;
595 throw new InvalidOperationException ();
598 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
600 Check.SourceAndPredicate (source, predicate);
602 return source.First (predicate, Fallback.Throw);
607 #region FirstOrDefault
609 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
611 Check.Source (source);
613 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
616 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
618 Check.SourceAndPredicate (source, predicate);
620 return source.First (predicate, Fallback.Default);
627 private static List<T> ContainsGroup<K, T> (
628 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
630 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
631 foreach (KeyValuePair<K, List<T>> value in items) {
632 if (comparerInUse.Equals (value.Key, key))
638 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
639 Func<TSource, TKey> keySelector)
641 return GroupBy<TSource, TKey> (source, keySelector, null);
644 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
645 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
647 Check.SourceAndKeySelector (source, keySelector);
649 return CreateGroupByIterator (source, keySelector, comparer);
652 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
653 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
655 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
656 List<TSource> nullList = new List<TSource> ();
658 int nullCounter = -1;
660 foreach (TSource element in source) {
661 TKey key = keySelector (element);
663 nullList.Add (element);
664 if (nullCounter == -1) {
665 nullCounter = counter;
669 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
671 group = new List<TSource> ();
672 groups.Add (key, group);
680 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
681 if (counter == nullCounter) {
682 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
683 yield return nullGroup;
686 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
687 yield return grouping;
692 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
693 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
695 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
698 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
699 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
701 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
703 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
704 List<TElement> nullList = new List<TElement> ();
706 int nullCounter = -1;
708 foreach (TSource item in source) {
709 TKey key = keySelector (item);
710 TElement element = elementSelector (item);
712 nullList.Add (element);
713 if (nullCounter == -1) {
714 nullCounter = counter;
718 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
720 group = new List<TElement> ();
721 groups.Add (key, group);
729 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
730 if (counter == nullCounter) {
731 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
732 yield return nullGroup;
735 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
736 yield return grouping;
741 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
742 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
743 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
745 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
748 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
749 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
750 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
751 IEqualityComparer<TKey> comparer)
753 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
754 source, keySelector, elementSelector, comparer);
756 foreach (IGrouping<TKey, TElement> group in groups)
757 yield return resultSelector (group.Key, group);
760 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
761 Func<TSource, TKey> keySelector,
762 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
764 return GroupBy (source, keySelector, resultSelector, null);
767 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
768 Func<TSource, TKey> keySelector,
769 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
770 IEqualityComparer<TKey> comparer)
772 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
774 foreach (IGrouping<TKey, TSource> group in groups)
775 yield return resultSelector (group.Key, group);
782 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
783 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
784 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
786 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
789 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
790 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
791 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
792 IEqualityComparer<TKey> comparer)
794 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
796 if (comparer == null)
797 comparer = EqualityComparer<TKey>.Default;
799 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
802 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
803 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
804 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
805 IEqualityComparer<TKey> comparer)
807 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
808 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
809 foreach (U element in inner)
811 K innerKey = innerKeySelector (element);
812 if (!innerKeys.ContainsKey (innerKey))
813 innerKeys.Add (innerKey, new List<U> ());
814 innerKeys[innerKey].Add (element);
817 foreach (TOuter element in outer) {
818 TKey outerKey = outerKeySelector (element);
819 if (innerKeys.Contains (outerKey))
820 yield return resultSelector (element, innerKeys [outerKey]);
822 yield return resultSelector (element, Empty<TInner> ());
830 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
832 return Intersect (first, second, null);
835 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
837 Check.FirstAndSecond (first, second);
839 if (comparer == null)
840 comparer = EqualityComparer<TSource>.Default;
842 return CreateIntersectIterator (first, second, comparer);
845 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
847 var items = new HashSet<TSource> (second, comparer);
848 foreach (TSource element in first) {
849 if (items.Contains (element))
850 yield return element;
858 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
859 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
860 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
862 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
864 if (comparer == null)
865 comparer = EqualityComparer<TKey>.Default;
867 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
870 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
871 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
872 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
874 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
875 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
876 foreach (U element in inner)
878 K innerKey = innerKeySelector (element);
879 if (!innerKeys.ContainsKey (innerKey))
880 innerKeys.Add (innerKey, new List<U> ());
881 innerKeys[innerKey].Add (element);
884 foreach (TOuter element in outer) {
885 TKey outerKey = outerKeySelector (element);
886 if (innerKeys.Contains (outerKey)) {
887 foreach (TInner innerElement in innerKeys [outerKey])
888 yield return resultSelector (element, innerElement);
893 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
894 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
895 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
897 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
904 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
907 var item = default (TSource);
909 foreach (var element in source) {
910 if (!predicate (element))
920 if (fallback == Fallback.Throw)
921 throw new InvalidOperationException ();
926 public static TSource Last<TSource> (this IEnumerable<TSource> source)
928 Check.Source (source);
930 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
933 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
935 Check.SourceAndPredicate (source, predicate);
937 return source.Last (predicate, Fallback.Throw);
942 #region LastOrDefault
944 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
946 Check.Source (source);
948 var list = source as IList<TSource>;
950 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
952 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
955 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
957 Check.SourceAndPredicate (source, predicate);
959 return source.Last (predicate, Fallback.Default);
966 public static long LongCount<TSource> (this IEnumerable<TSource> source)
968 Check.Source (source);
971 var array = source as TSource [];
973 return array.LongLength;
977 using (var enumerator = source.GetEnumerator ())
978 while (enumerator.MoveNext ())
984 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
986 Check.SourceAndSelector (source, selector);
989 foreach (TSource element in source)
990 if (selector (element))
1000 public static int Max (this IEnumerable<int> source)
1002 Check.Source (source);
1004 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
1007 public static long Max (this IEnumerable<long> source)
1009 Check.Source (source);
1011 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
1014 public static double Max (this IEnumerable<double> source)
1016 Check.Source (source);
1018 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
1021 public static float Max (this IEnumerable<float> source)
1023 Check.Source (source);
1025 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
1028 public static decimal Max (this IEnumerable<decimal> source)
1030 Check.Source (source);
1032 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1035 public static int? Max (this IEnumerable<int?> source)
1037 Check.Source (source);
1039 return IterateNullable (source, int.MinValue, (a, b) => a > b);
1042 public static long? Max (this IEnumerable<long?> source)
1044 Check.Source (source);
1046 return IterateNullable (source, long.MinValue, (a, b) => a > b);
1049 public static double? Max (this IEnumerable<double?> source)
1051 Check.Source (source);
1053 return IterateNullable (source, double.MinValue, (a, b) => a > b);
1056 public static float? Max (this IEnumerable<float?> source)
1058 Check.Source (source);
1060 return IterateNullable (source, float.MinValue, (a, b) => a > b);
1063 public static decimal? Max (this IEnumerable<decimal?> source)
1065 Check.Source (source);
1067 return IterateNullable (source, decimal.MinValue, (a, b) => a > b);
1070 static T? IterateNullable<T> (IEnumerable<T?> source, T initValue, Func<T?, T?, bool> selector) where T : struct
1073 T? value = initValue;
1074 foreach (var element in source) {
1075 if (!element.HasValue)
1078 if (selector (element.Value, value))
1089 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1091 Check.Source (source);
1093 bool notAssigned = true;
1094 TSource maximum = default (TSource);
1096 foreach (TSource element in source) {
1099 notAssigned = false;
1102 if (element is IComparable<TSource>)
1103 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1104 else if (element is System.IComparable)
1105 comparison = ((System.IComparable) element).CompareTo (maximum);
1107 throw new ArgumentNullException ();
1116 throw new InvalidOperationException ();
1121 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1123 Check.SourceAndSelector (source, selector);
1125 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1128 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1130 Check.SourceAndSelector (source, selector);
1132 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1135 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1137 Check.SourceAndSelector (source, selector);
1139 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1142 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1144 Check.SourceAndSelector (source, selector);
1146 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1149 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1151 Check.SourceAndSelector (source, selector);
1153 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1156 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1159 foreach (var element in source) {
1160 initValue = selector (element, initValue);
1165 throw new InvalidOperationException ();
1170 static U? IterateNullable<T, U> (IEnumerable<T> source, U initialValue, Func<T, U?, U?> selector) where U : struct
1173 U? value = initialValue;
1174 foreach (var element in source) {
1175 value = selector (element, value);
1176 if (!value.HasValue)
1188 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1190 Check.SourceAndSelector (source, selector);
1192 return IterateNullable (source, int.MinValue, (a, b) => {
1193 var v = selector (a); return v > b ? v : b;
1197 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1199 Check.SourceAndSelector (source, selector);
1201 return IterateNullable (source, long.MinValue, (a, b) => {
1202 var v = selector (a); return v > b ? v : b;
1206 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1208 Check.SourceAndSelector (source, selector);
1210 return IterateNullable (source, double.MinValue, (a, b) => {
1211 var v = selector (a); return v > b ? v : b;
1215 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1217 Check.SourceAndSelector (source, selector);
1219 return IterateNullable (source, float.MinValue, (a, b) => {
1220 var v = selector (a); return v > b ? v : b;
1224 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1226 Check.SourceAndSelector (source, selector);
1228 return IterateNullable (source, decimal.MinValue, (a, b) => {
1229 var v = selector (a); return v > b ? v : b;
1233 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1235 Check.SourceAndSelector (source, selector);
1237 bool notAssigned = true;
1238 TResult maximum = default (TResult);
1240 foreach (TSource item in source) {
1241 TResult element = selector (item);
1244 notAssigned = false;
1247 if (element is IComparable<TResult>)
1248 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1249 else if (element is System.IComparable)
1250 comparison = ((System.IComparable) element).CompareTo (maximum);
1252 throw new ArgumentNullException ();
1261 throw new InvalidOperationException ();
1270 public static int Min (this IEnumerable<int> source)
1272 Check.Source (source);
1274 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1277 public static long Min (this IEnumerable<long> source)
1279 Check.Source (source);
1281 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1284 public static double Min (this IEnumerable<double> source)
1286 Check.Source (source);
1288 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1291 public static float Min (this IEnumerable<float> source)
1293 Check.Source (source);
1295 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1298 public static decimal Min (this IEnumerable<decimal> source)
1300 Check.Source (source);
1302 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1305 public static int? Min (this IEnumerable<int?> source)
1307 Check.Source (source);
1309 return IterateNullable (source, int.MaxValue, (a, b) => a < b);
1312 public static long? Min (this IEnumerable<long?> source)
1314 Check.Source (source);
1316 return IterateNullable (source, long.MaxValue, (a, b) => a < b);
1319 public static double? Min (this IEnumerable<double?> source)
1321 Check.Source (source);
1323 return IterateNullable (source, double.MaxValue, (a, b) => a < b);
1326 public static float? Min (this IEnumerable<float?> source)
1328 Check.Source (source);
1330 return IterateNullable (source, float.MaxValue, (a, b) => a < b);
1333 public static decimal? Min (this IEnumerable<decimal?> source)
1335 Check.Source (source);
1337 return IterateNullable (source, decimal.MaxValue, (a, b) => a < b);
1340 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1342 Check.Source (source);
1344 bool notAssigned = true;
1345 TSource minimum = default (TSource);
1347 foreach (TSource element in source) {
1350 notAssigned = false;
1353 if (element is IComparable<TSource>)
1354 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1355 else if (element is System.IComparable)
1356 comparison = ((System.IComparable) element).CompareTo (minimum);
1358 throw new ArgumentNullException ();
1367 throw new InvalidOperationException ();
1372 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1374 Check.SourceAndSelector (source, selector);
1376 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1379 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1381 Check.SourceAndSelector (source, selector);
1383 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1386 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1388 Check.SourceAndSelector (source, selector);
1390 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1393 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1395 Check.SourceAndSelector (source, selector);
1397 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1400 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1402 Check.SourceAndSelector (source, selector);
1404 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1407 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1409 Check.SourceAndSelector (source, selector);
1411 return IterateNullable (source, int.MaxValue, (a, b) => {
1412 var v = selector (a); return v < b ? v : b;
1416 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1418 Check.SourceAndSelector (source, selector);
1420 return IterateNullable (source, long.MaxValue, (a, b) => {
1421 var v = selector (a); return v < b ? v : b;
1425 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1427 Check.SourceAndSelector (source, selector);
1429 return IterateNullable (source, float.MaxValue, (a, b) => {
1430 var v = selector (a); return v < b ? v : b;
1434 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1436 Check.SourceAndSelector (source, selector);
1438 return IterateNullable (source, double.MaxValue, (a, b) => {
1439 var v = selector (a); return v < b ? v : b;
1443 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1445 Check.SourceAndSelector (source, selector);
1447 return IterateNullable (source, decimal.MaxValue, (a, b) => {
1448 var v = selector (a); return v < b ? v : b;
1452 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1454 Check.SourceAndSelector (source, selector);
1456 bool notAssigned = true;
1457 TResult minimum = default (TResult);
1459 foreach (TSource item in source) {
1460 TResult element = selector (item);
1463 notAssigned = false;
1466 if (element is IComparable<TResult>)
1467 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1468 else if (element is System.IComparable)
1469 comparison = ((System.IComparable) element).CompareTo (minimum);
1471 throw new ArgumentNullException ();
1480 throw new InvalidOperationException ();
1489 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1491 Check.Source (source);
1493 return CreateOfTypeIterator<TResult> (source);
1496 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1498 foreach (object element in source)
1499 if (element is TResult)
1500 yield return (TResult) element;
1507 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1508 Func<TSource, TKey> keySelector)
1510 return OrderBy<TSource, TKey> (source, keySelector, null);
1513 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1514 Func<TSource, TKey> keySelector,
1515 IComparer<TKey> comparer)
1517 Check.SourceAndKeySelector (source, keySelector);
1519 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1524 #region OrderByDescending
1526 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1527 Func<TSource, TKey> keySelector)
1529 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1532 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1533 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1535 Check.SourceAndKeySelector (source, keySelector);
1537 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1544 public static IEnumerable<int> Range (int start, int count)
1547 throw new ArgumentOutOfRangeException ("count");
1549 long upto = ((long) start + count) - 1;
1551 if (upto > int.MaxValue)
1552 throw new ArgumentOutOfRangeException ();
1554 return CreateRangeIterator (start, (int) upto);
1557 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1559 for (int i = start; i <= upto; i++)
1567 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1570 throw new ArgumentOutOfRangeException ();
1572 return CreateRepeatIterator (element, count);
1575 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1577 for (int i = 0; i < count; i++)
1578 yield return element;
1585 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1587 Check.Source (source);
1589 var list = source as IList<TSource>;
1591 list = new List<TSource> (source);
1593 return CreateReverseIterator (list);
1596 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1598 for (int i = source.Count; i > 0; --i)
1599 yield return source [i - 1];
1606 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1608 Check.SourceAndSelector (source, selector);
1610 return CreateSelectIterator (source, selector);
1613 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1615 foreach (var element in source)
1616 yield return selector (element);
1619 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1621 Check.SourceAndSelector (source, selector);
1623 return CreateSelectIterator (source, selector);
1626 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1629 foreach (TSource element in source) {
1630 yield return selector (element, counter);
1639 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1641 Check.SourceAndSelector (source, selector);
1643 return CreateSelectManyIterator (source, selector);
1646 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1648 foreach (TSource element in source)
1649 foreach (TResult item in selector (element))
1653 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1655 Check.SourceAndSelector (source, selector);
1657 return CreateSelectManyIterator (source, selector);
1660 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1663 foreach (TSource element in source) {
1664 foreach (TResult item in selector (element, counter))
1670 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1671 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1673 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1675 return CreateSelectManyIterator (source, collectionSelector, selector);
1678 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1679 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1681 foreach (TSource element in source)
1682 foreach (TCollection collection in collectionSelector (element))
1683 yield return selector (element, collection);
1686 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1687 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1689 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1691 return CreateSelectManyIterator (source, collectionSelector, selector);
1694 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1695 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1698 foreach (TSource element in source)
1699 foreach (TCollection collection in collectionSelector (element, counter++))
1700 yield return selector (element, collection);
1707 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1710 var item = default (TSource);
1712 foreach (var element in source) {
1713 if (!predicate (element))
1717 throw new InvalidOperationException ();
1723 if (!found && fallback == Fallback.Throw)
1724 throw new InvalidOperationException ();
1729 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1731 Check.Source (source);
1733 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1736 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1738 Check.SourceAndPredicate (source, predicate);
1740 return source.Single (predicate, Fallback.Throw);
1745 #region SingleOrDefault
1747 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1749 Check.Source (source);
1751 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1754 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1756 Check.SourceAndPredicate (source, predicate);
1758 return source.Single (predicate, Fallback.Default);
1765 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1767 Check.Source (source);
1769 return CreateSkipIterator (source, count);
1772 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1775 foreach (var element in source) {
1779 yield return element;
1787 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1789 Check.SourceAndPredicate (source, predicate);
1791 return CreateSkipWhileIterator (source, predicate);
1794 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1798 foreach (TSource element in source) {
1800 yield return element;
1802 if (!predicate (element)) {
1803 yield return element;
1809 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1811 Check.SourceAndPredicate (source, predicate);
1813 return CreateSkipWhileIterator (source, predicate);
1816 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1821 foreach (TSource element in source) {
1823 yield return element;
1825 if (!predicate (element, counter)) {
1826 yield return element;
1837 public static int Sum (this IEnumerable<int> source)
1839 Check.Source (source);
1841 return Sum<int, int> (source, (a, b) => a + b);
1844 public static int? Sum (this IEnumerable<int?> source)
1846 Check.Source (source);
1848 return source.SumNullable<int?, int?> (0, (a, b) => a.HasValue ? a + b : a);
1851 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1853 Check.SourceAndSelector (source, selector);
1855 return Sum<TSource, int> (source, (a, b) => a + selector (b));
1858 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1860 Check.SourceAndSelector (source, selector);
1862 return source.SumNullable<TSource, int?> (0, (a, b) => {
1863 var value = selector (b);
1864 return value.HasValue ? a + value.Value : a;
1868 public static long Sum (this IEnumerable<long> source)
1870 Check.Source (source);
1872 return Sum<long, long> (source, (a, b) => a + b);
1875 public static long? Sum (this IEnumerable<long?> source)
1877 Check.Source (source);
1879 return source.SumNullable<long?, long?> (0, (a, b) => a.HasValue ? a + b : a);
1882 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1884 Check.SourceAndSelector (source, selector);
1886 return Sum<TSource, long> (source, (a, b) => a + selector (b));
1889 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1891 Check.SourceAndSelector (source, selector);
1893 return source.SumNullable<TSource, long?> (0, (a, b) => {
1894 var value = selector (b);
1895 return value.HasValue ? a + value.Value : a;
1899 public static double Sum (this IEnumerable<double> source)
1901 Check.Source (source);
1903 return Sum<double, double> (source, (a, b) => a + b);
1906 public static double? Sum (this IEnumerable<double?> source)
1908 Check.Source (source);
1910 return source.SumNullable<double?, double?> (0, (a, b) => a.HasValue ? a + b : a);
1913 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1915 Check.SourceAndSelector (source, selector);
1917 return Sum<TSource, double> (source, (a, b) => a + selector (b));
1920 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1922 Check.SourceAndSelector (source, selector);
1924 return source.SumNullable<TSource, double?> (0, (a, b) => {
1925 var value = selector (b);
1926 return value.HasValue ? a + value.Value : a;
1930 public static float Sum (this IEnumerable<float> source)
1932 Check.Source (source);
1934 return Sum<float, float> (source, (a, b) => a + b);
1937 public static float? Sum (this IEnumerable<float?> source)
1939 Check.Source (source);
1941 return source.SumNullable<float?, float?> (0, (a, b) => a.HasValue ? a + b : a);
1944 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1946 Check.SourceAndSelector (source, selector);
1948 return Sum<TSource, float> (source, (a, b) => a + selector (b));
1951 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1953 Check.SourceAndSelector (source, selector);
1955 return source.SumNullable<TSource, float?> (0, (a, b) => {
1956 var value = selector (b);
1957 return value.HasValue ? a + value.Value : a;
1961 public static decimal Sum (this IEnumerable<decimal> source)
1963 Check.Source (source);
1965 return Sum<decimal, decimal> (source, (a, b) => a + b);
1968 public static decimal? Sum (this IEnumerable<decimal?> source)
1970 Check.Source (source);
1972 return source.SumNullable<decimal?, decimal?> (0, (a, b) => a.HasValue ? a + b : a);
1975 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1977 Check.SourceAndSelector (source, selector);
1979 return Sum<TSource, decimal> (source, (a, b) => a + selector (b));
1982 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1984 Check.SourceAndSelector (source, selector);
1986 return source.SumNullable<TSource, decimal?> (0, (a, b) => {
1987 var value = selector (b);
1988 return value.HasValue ? a + value.Value : a;
1992 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1994 TR total = default (TR);
1996 foreach (var element in source) {
1997 total = selector (total, element);
2004 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, TR zero, Func<TR, TA, TR> selector)
2007 foreach (var element in source) {
2008 total = selector (total, element);
2018 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2020 Check.Source (source);
2022 return CreateTakeIterator (source, count);
2025 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2031 foreach (TSource element in source) {
2032 yield return element;
2034 if (++counter == count)
2043 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2045 Check.SourceAndPredicate (source, predicate);
2047 return CreateTakeWhileIterator (source, predicate);
2050 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2052 foreach (var element in source) {
2053 if (!predicate (element))
2056 yield return element;
2060 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2062 Check.SourceAndPredicate (source, predicate);
2064 return CreateTakeWhileIterator (source, predicate);
2067 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2070 foreach (var element in source) {
2071 if (!predicate (element, counter))
2074 yield return element;
2083 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2085 return ThenBy<TSource, TKey> (source, keySelector, null);
2088 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2089 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2091 Check.SourceAndKeySelector (source, keySelector);
2093 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2098 #region ThenByDescending
2100 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2101 Func<TSource, TKey> keySelector)
2103 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2106 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2107 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2109 Check.SourceAndKeySelector (source, keySelector);
2111 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2118 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2120 Check.Source (source);
2122 var collection = source as ICollection<TSource>;
2123 if (collection != null) {
2124 var array = new TSource [collection.Count];
2125 collection.CopyTo (array, 0);
2129 return new List<TSource> (source).ToArray ();
2134 #region ToDictionary
2135 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2136 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2138 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2141 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2142 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2144 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2146 if (comparer == null)
2147 comparer = EqualityComparer<TKey>.Default;
2149 var dict = new Dictionary<TKey, TElement> (comparer);
2150 foreach (var e in source)
2151 dict.Add (keySelector (e), elementSelector (e));
2156 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2157 Func<TSource, TKey> keySelector)
2159 return ToDictionary (source, keySelector, null);
2162 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2163 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2165 Check.SourceAndKeySelector (source, keySelector);
2167 if (comparer == null)
2168 comparer = EqualityComparer<TKey>.Default;
2170 var dict = new Dictionary<TKey, TSource> (comparer);
2171 foreach (var e in source)
2172 dict.Add (keySelector (e), e);
2180 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2182 Check.Source (source);
2184 return new List<TSource> (source);
2190 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2192 return ToLookup<TSource, TKey> (source, keySelector, null);
2195 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2196 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2198 Check.SourceAndKeySelector (source, keySelector);
2200 var dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2201 foreach (TSource element in source) {
2202 TKey key = keySelector (element);
2204 throw new ArgumentNullException ();
2205 if (!dictionary.ContainsKey (key))
2206 dictionary.Add (key, new List<TSource> ());
2207 dictionary [key].Add (element);
2209 return new Lookup<TKey, TSource> (dictionary);
2212 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2213 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2215 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2218 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2219 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2221 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2223 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2224 foreach (TSource element in source) {
2225 TKey key = keySelector (element);
2227 throw new ArgumentNullException ();
2228 if (!dictionary.ContainsKey (key))
2229 dictionary.Add (key, new List<TElement> ());
2230 dictionary [key].Add (elementSelector (element));
2232 return new Lookup<TKey, TElement> (dictionary);
2237 #region SequenceEqual
2239 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2241 return first.SequenceEqual (second, null);
2244 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2246 Check.FirstAndSecond (first, second);
2248 if (comparer == null)
2249 comparer = EqualityComparer<TSource>.Default;
2251 var first_enumerator = first.GetEnumerator ();
2252 var second_enumerator = second.GetEnumerator ();
2254 while (first_enumerator.MoveNext ()) {
2255 if (!second_enumerator.MoveNext ())
2258 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2262 return !second_enumerator.MoveNext ();
2269 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2271 Check.FirstAndSecond (first, second);
2273 return first.Union (second, null);
2276 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2278 Check.FirstAndSecond (first, second);
2280 if (comparer == null)
2281 comparer = EqualityComparer<TSource>.Default;
2283 return CreateUnionIterator (first, second, comparer);
2286 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2288 var items = new HashSet<TSource> (comparer);
2289 foreach (var element in first) {
2290 if (! items.Contains (element)) {
2291 items.Add (element);
2292 yield return element;
2296 foreach (var element in second) {
2297 if (! items.Contains (element, comparer)) {
2298 items.Add (element);
2299 yield return element;
2308 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2310 Check.SourceAndPredicate (source, predicate);
2312 return CreateWhereIterator (source, predicate);
2315 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2317 foreach (TSource element in source)
2318 if (predicate (element))
2319 yield return element;
2322 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2324 Check.SourceAndPredicate (source, predicate);
2326 return CreateWhereIterator (source, predicate);
2329 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2332 foreach (TSource element in source) {
2333 if (predicate (element, counter))
2334 yield return element;
2341 class ReadOnlyCollectionOf<T> {
2342 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2345 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2348 return ReadOnlyCollectionOf<TSource>.Empty;
2350 var ro = source as ReadOnlyCollection<TSource>;
2354 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());