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;
53 public static readonly Func<T, T> Identity = (t) => t;
58 public static TSource Aggregate<TSource> (this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
60 Check.SourceAndFunc (source, func);
62 // custom foreach so that we can efficiently throw an exception
63 // if zero elements and treat the first element differently
64 using (var enumerator = source.GetEnumerator ()) {
65 if (!enumerator.MoveNext ())
66 throw new InvalidOperationException ("No elements in source list");
68 TSource folded = enumerator.Current;
69 while (enumerator.MoveNext ())
70 folded = func (folded, enumerator.Current);
75 public static TAccumulate Aggregate<TSource, TAccumulate> (this IEnumerable<TSource> source,
76 TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
78 Check.SourceAndFunc (source, func);
80 TAccumulate folded = seed;
81 foreach (TSource element in source)
82 folded = func (folded, element);
87 public static TResult Aggregate<TSource, TAccumulate, TResult> (this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
89 Check.SourceAndFunc (source, func);
90 if (resultSelector == null)
91 throw new ArgumentNullException ("resultSelector");
94 foreach (var e in source)
95 result = func (result, e);
97 return resultSelector (result);
104 public static bool All<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
106 Check.SourceAndPredicate (source, predicate);
108 foreach (var element in source)
109 if (!predicate (element))
119 public static bool Any<TSource> (this IEnumerable<TSource> source)
121 Check.Source (source);
123 var collection = source as ICollection<TSource>;
124 if (collection != null)
125 return collection.Count > 0;
127 using (var enumerator = source.GetEnumerator ())
128 return enumerator.MoveNext ();
131 public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
133 Check.SourceAndPredicate (source, predicate);
135 foreach (TSource element in source)
136 if (predicate (element))
146 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
155 public static double Average (this IEnumerable<int> source)
157 return Average<int, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
160 public static double Average (this IEnumerable<long> source)
162 return Average<long, long, double> (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
165 public static double Average (this IEnumerable<double> source)
167 return Average<double, double, double> (source, (a, b) => a + b, (a, b) => a / b);
170 public static float Average (this IEnumerable<float> source)
172 return Average<float, double, float> (source, (a, b) => a + b, (a, b) => (float) a / (float) b);
175 public static decimal Average (this IEnumerable<decimal> source)
177 return Average<decimal, decimal, decimal> (source, (a, b) => a + b, (a, b) => a / b);
180 static TResult Average<TElement, TAggregate, TResult> (this IEnumerable<TElement> source,
181 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
182 where TElement : struct
183 where TAggregate : struct
184 where TResult : struct
186 Check.Source (source);
188 var total = default (TAggregate);
190 foreach (var element in source) {
191 total = func (total, element);
196 throw new InvalidOperationException ();
198 return result (total, counter);
201 static TResult? AverageNullable<TElement, TAggregate, TResult> (this IEnumerable<TElement?> source,
202 Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
203 where TElement : struct
204 where TAggregate : struct
205 where TResult : struct
207 Check.Source (source);
209 var total = default (TAggregate);
211 foreach (var element in source) {
212 if (!element.HasValue)
215 total = func (total, element.Value);
222 return new TResult? (result (total, counter));
225 public static double? Average (this IEnumerable<int?> source)
227 Check.Source (source);
229 return source.AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
232 public static double? Average (this IEnumerable<long?> source)
234 Check.Source (source);
236 return source.AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / b);
239 public static double? Average (this IEnumerable<double?> source)
241 Check.Source (source);
243 return source.AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
246 public static decimal? Average (this IEnumerable<decimal?> source)
248 Check.Source (source);
250 return source.AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
253 public static float? Average (this IEnumerable<float?> source)
255 Check.Source (source);
257 return source.AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
260 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
262 Check.SourceAndSelector (source, selector);
264 return source.Select (selector).Average<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
267 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
269 Check.SourceAndSelector (source, selector);
271 return source.Select (selector).AverageNullable<int, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
274 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
276 Check.SourceAndSelector (source, selector);
278 return source.Select (selector).Average<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
281 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
283 Check.SourceAndSelector (source, selector);
285 return source.Select (selector).AverageNullable<long, long, double> ((a, b) => a + b, (a, b) => (double) a / (double) b);
288 public static double Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
290 Check.SourceAndSelector (source, selector);
292 return source.Select (selector).Average<double, double, double> ((a, b) => a + b, (a, b) => a / b);
295 public static double? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
297 Check.SourceAndSelector (source, selector);
299 return source.Select (selector).AverageNullable<double, double, double> ((a, b) => a + b, (a, b) => a / b);
302 public static float Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
304 Check.SourceAndSelector (source, selector);
306 return source.Select (selector).Average<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
309 public static float? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
311 Check.SourceAndSelector (source, selector);
313 return source.Select (selector).AverageNullable<float, double, float> ((a, b) => a + b, (a, b) => (float) a / (float) b);
316 public static decimal Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
318 Check.SourceAndSelector (source, selector);
320 return source.Select (selector).Average<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
323 public static decimal? Average<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
325 Check.SourceAndSelector (source, selector);
327 return source.Select (selector).AverageNullable<decimal, decimal, decimal> ((a, b) => a + b, (a, b) => a / b);
334 public static IEnumerable<TResult> Cast<TResult> (this IEnumerable source)
336 Check.Source (source);
338 return CreateCastIterator<TResult> (source);
341 static IEnumerable<TResult> CreateCastIterator<TResult> (IEnumerable source)
343 foreach (TResult element in source)
344 yield return element;
351 public static IEnumerable<TSource> Concat<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
353 Check.FirstAndSecond (first, second);
355 return CreateConcatIterator (first, second);
358 static IEnumerable<TSource> CreateConcatIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second)
360 foreach (TSource element in first)
361 yield return element;
362 foreach (TSource element in second)
363 yield return element;
370 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value)
372 var collection = source as ICollection<TSource>;
373 if (collection != null)
374 return collection.Contains (value);
376 return Contains<TSource> (source, value, null);
379 public static bool Contains<TSource> (this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
381 Check.Source (source);
383 if (comparer == null)
384 comparer = EqualityComparer<TSource>.Default;
386 foreach (var element in source)
387 if (comparer.Equals (element, value))
396 public static int Count<TSource> (this IEnumerable<TSource> source)
398 Check.Source (source);
400 var collection = source as ICollection<TSource>;
401 if (collection != null)
402 return collection.Count;
405 using (var enumerator = source.GetEnumerator ())
406 while (enumerator.MoveNext ())
412 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
414 Check.SourceAndSelector (source, selector);
417 foreach (var element in source)
418 if (selector (element))
426 #region DefaultIfEmpty
428 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source)
430 return DefaultIfEmpty (source, default (TSource));
433 public static IEnumerable<TSource> DefaultIfEmpty<TSource> (this IEnumerable<TSource> source, TSource defaultValue)
435 Check.Source (source);
437 return CreateDefaultIfEmptyIterator (source, defaultValue);
440 static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource> (IEnumerable<TSource> source, TSource defaultValue)
443 foreach (TSource item in source) {
449 yield return defaultValue;
456 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source)
458 return Distinct<TSource> (source, null);
461 public static IEnumerable<TSource> Distinct<TSource> (this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
463 Check.Source (source);
465 if (comparer == null)
466 comparer = EqualityComparer<TSource>.Default;
468 return CreateDistinctIterator (source, comparer);
471 static IEnumerable<TSource> CreateDistinctIterator<TSource> (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
473 var items = new HashSet<TSource> (comparer);
474 foreach (var element in source) {
475 if (! items.Contains (element)) {
477 yield return element;
486 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
490 foreach (var element in source) {
491 if (index == counter++)
495 if (fallback == Fallback.Throw)
496 throw new ArgumentOutOfRangeException ();
498 return default (TSource);
501 public static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index)
503 Check.Source (source);
506 throw new ArgumentOutOfRangeException ();
508 var list = source as IList<TSource>;
512 return source.ElementAt (index, Fallback.Throw);
517 #region ElementAtOrDefault
519 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
521 Check.Source (source);
524 return default (TSource);
526 var list = source as IList<TSource>;
528 return index < list.Count ? list [index] : default (TSource);
530 return source.ElementAt (index, Fallback.Default);
537 public static IEnumerable<TResult> Empty<TResult> ()
539 return new TResult [0];
546 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
548 return Except (first, second, null);
551 public static IEnumerable<TSource> Except<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
553 Check.FirstAndSecond (first, second);
555 if (comparer == null)
556 comparer = EqualityComparer<TSource>.Default;
558 return CreateExceptIterator (first, second, comparer);
561 static IEnumerable<TSource> CreateExceptIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
563 var items = new HashSet<TSource> (second, comparer);
564 foreach (var element in first) {
565 if (!items.Contains (element, comparer))
566 yield return element;
574 static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
576 foreach (var element in source)
577 if (predicate (element))
580 if (fallback == Fallback.Throw)
581 throw new InvalidOperationException ();
583 return default (TSource);
586 public static TSource First<TSource> (this IEnumerable<TSource> source)
588 Check.Source (source);
590 var list = source as IList<TSource>;
595 throw new InvalidOperationException ();
597 using (var enumerator = source.GetEnumerator ()) {
598 if (enumerator.MoveNext ())
599 return enumerator.Current;
603 throw new InvalidOperationException ();
606 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
608 Check.SourceAndPredicate (source, predicate);
610 return source.First (predicate, Fallback.Throw);
615 #region FirstOrDefault
617 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
619 Check.Source (source);
621 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
624 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
626 Check.SourceAndPredicate (source, predicate);
628 return source.First (predicate, Fallback.Default);
635 private static List<T> ContainsGroup<K, T> (
636 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
638 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
639 foreach (KeyValuePair<K, List<T>> value in items) {
640 if (comparerInUse.Equals (value.Key, key))
646 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
647 Func<TSource, TKey> keySelector)
649 return GroupBy<TSource, TKey> (source, keySelector, null);
652 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
653 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
655 Check.SourceAndKeySelector (source, keySelector);
657 return CreateGroupByIterator (source, keySelector, comparer);
660 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
661 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
663 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
664 List<TSource> nullList = new List<TSource> ();
666 int nullCounter = -1;
668 foreach (TSource element in source) {
669 TKey key = keySelector (element);
671 nullList.Add (element);
672 if (nullCounter == -1) {
673 nullCounter = counter;
677 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
679 group = new List<TSource> ();
680 groups.Add (key, group);
688 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
689 if (counter == nullCounter) {
690 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
691 yield return nullGroup;
694 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
695 yield return grouping;
700 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
701 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
703 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
706 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
707 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
709 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
711 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
712 List<TElement> nullList = new List<TElement> ();
714 int nullCounter = -1;
716 foreach (TSource item in source) {
717 TKey key = keySelector (item);
718 TElement element = elementSelector (item);
720 nullList.Add (element);
721 if (nullCounter == -1) {
722 nullCounter = counter;
726 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
728 group = new List<TElement> ();
729 groups.Add (key, group);
737 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
738 if (counter == nullCounter) {
739 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
740 yield return nullGroup;
743 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
744 yield return grouping;
749 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
750 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
751 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
753 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
756 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
757 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
758 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
759 IEqualityComparer<TKey> comparer)
761 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
762 source, keySelector, elementSelector, comparer);
764 foreach (IGrouping<TKey, TElement> group in groups)
765 yield return resultSelector (group.Key, group);
768 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
769 Func<TSource, TKey> keySelector,
770 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
772 return GroupBy (source, keySelector, resultSelector, null);
775 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
776 Func<TSource, TKey> keySelector,
777 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
778 IEqualityComparer<TKey> comparer)
780 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
782 foreach (IGrouping<TKey, TSource> group in groups)
783 yield return resultSelector (group.Key, group);
790 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
791 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
792 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
794 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
797 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
798 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
799 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
800 IEqualityComparer<TKey> comparer)
802 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
804 if (comparer == null)
805 comparer = EqualityComparer<TKey>.Default;
807 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
810 static IEnumerable<TResult> CreateGroupJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
811 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
812 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
813 IEqualityComparer<TKey> comparer)
815 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
816 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
817 foreach (U element in inner)
819 K innerKey = innerKeySelector (element);
820 if (!innerKeys.ContainsKey (innerKey))
821 innerKeys.Add (innerKey, new List<U> ());
822 innerKeys[innerKey].Add (element);
825 foreach (TOuter element in outer) {
826 TKey outerKey = outerKeySelector (element);
827 if (innerKeys.Contains (outerKey))
828 yield return resultSelector (element, innerKeys [outerKey]);
830 yield return resultSelector (element, Empty<TInner> ());
838 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
840 return Intersect (first, second, null);
843 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
845 Check.FirstAndSecond (first, second);
847 if (comparer == null)
848 comparer = EqualityComparer<TSource>.Default;
850 return CreateIntersectIterator (first, second, comparer);
853 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
855 var items = new HashSet<TSource> (second, comparer);
856 foreach (TSource element in first) {
857 if (items.Contains (element))
858 yield return element;
866 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
867 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
868 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
870 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
872 if (comparer == null)
873 comparer = EqualityComparer<TKey>.Default;
875 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
878 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
879 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
880 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
882 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
883 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
884 foreach (U element in inner)
886 K innerKey = innerKeySelector (element);
887 if (!innerKeys.ContainsKey (innerKey))
888 innerKeys.Add (innerKey, new List<U> ());
889 innerKeys[innerKey].Add (element);
892 foreach (TOuter element in outer) {
893 TKey outerKey = outerKeySelector (element);
894 if (innerKeys.Contains (outerKey)) {
895 foreach (TInner innerElement in innerKeys [outerKey])
896 yield return resultSelector (element, innerElement);
901 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
902 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
903 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
905 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
912 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
915 var item = default (TSource);
917 foreach (var element in source) {
918 if (!predicate (element))
928 if (fallback == Fallback.Throw)
929 throw new InvalidOperationException ();
934 public static TSource Last<TSource> (this IEnumerable<TSource> source)
936 Check.Source (source);
938 var collection = source as ICollection<TSource>;
939 if (collection != null && collection.Count == 0)
940 throw new InvalidOperationException ();
942 var list = source as IList<TSource>;
944 return list [list.Count - 1];
946 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
949 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
951 Check.SourceAndPredicate (source, predicate);
953 return source.Last (predicate, Fallback.Throw);
958 #region LastOrDefault
960 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
962 Check.Source (source);
964 var list = source as IList<TSource>;
966 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
968 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
971 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
973 Check.SourceAndPredicate (source, predicate);
975 return source.Last (predicate, Fallback.Default);
982 public static long LongCount<TSource> (this IEnumerable<TSource> source)
984 Check.Source (source);
987 var array = source as TSource [];
989 return array.LongLength;
993 using (var enumerator = source.GetEnumerator ())
994 while (enumerator.MoveNext ())
1000 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
1002 Check.SourceAndSelector (source, selector);
1005 foreach (TSource element in source)
1006 if (selector (element))
1016 public static int Max (this IEnumerable<int> source)
1018 Check.Source (source);
1020 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
1023 public static long Max (this IEnumerable<long> source)
1025 Check.Source (source);
1027 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
1030 public static double Max (this IEnumerable<double> source)
1032 Check.Source (source);
1034 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
1037 public static float Max (this IEnumerable<float> source)
1039 Check.Source (source);
1041 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
1044 public static decimal Max (this IEnumerable<decimal> source)
1046 Check.Source (source);
1048 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1051 public static int? Max (this IEnumerable<int?> source)
1053 Check.Source (source);
1055 return IterateNullable (source, int.MinValue, (a, b) => a > b);
1058 public static long? Max (this IEnumerable<long?> source)
1060 Check.Source (source);
1062 return IterateNullable (source, long.MinValue, (a, b) => a > b);
1065 public static double? Max (this IEnumerable<double?> source)
1067 Check.Source (source);
1069 return IterateNullable (source, double.MinValue, (a, b) => a > b);
1072 public static float? Max (this IEnumerable<float?> source)
1074 Check.Source (source);
1076 return IterateNullable (source, float.MinValue, (a, b) => a > b);
1079 public static decimal? Max (this IEnumerable<decimal?> source)
1081 Check.Source (source);
1083 return IterateNullable (source, decimal.MinValue, (a, b) => a > b);
1086 static T? IterateNullable<T> (IEnumerable<T?> source, T initValue, Func<T?, T?, bool> selector) where T : struct
1089 T? value = initValue;
1090 foreach (var element in source) {
1091 if (!element.HasValue)
1094 if (selector (element.Value, value))
1106 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1108 Check.Source (source);
1110 bool notAssigned = true;
1111 TSource maximum = default (TSource);
1113 foreach (TSource element in source) {
1116 notAssigned = false;
1119 if (element is IComparable<TSource>)
1120 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1121 else if (element is System.IComparable)
1122 comparison = ((System.IComparable) element).CompareTo (maximum);
1124 throw new ArgumentNullException ();
1133 throw new InvalidOperationException ();
1138 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1140 Check.SourceAndSelector (source, selector);
1142 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1145 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1147 Check.SourceAndSelector (source, selector);
1149 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1152 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1154 Check.SourceAndSelector (source, selector);
1156 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1159 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1161 Check.SourceAndSelector (source, selector);
1163 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1166 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1168 Check.SourceAndSelector (source, selector);
1170 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1173 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1176 foreach (var element in source) {
1177 initValue = selector (element, initValue);
1182 throw new InvalidOperationException ();
1187 static U? IterateNullable<T, U> (IEnumerable<T> source, U initialValue, Func<T, U?, U?> selector) where U : struct
1190 U? value = initialValue;
1191 foreach (var element in source) {
1192 value = selector (element, value);
1193 if (!value.HasValue)
1205 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1207 Check.SourceAndSelector (source, selector);
1209 return IterateNullable (source, int.MinValue, (a, b) => {
1210 var v = selector (a); return v > b ? v : b;
1214 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1216 Check.SourceAndSelector (source, selector);
1218 return IterateNullable (source, long.MinValue, (a, b) => {
1219 var v = selector (a); return v > b ? v : b;
1223 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1225 Check.SourceAndSelector (source, selector);
1227 return IterateNullable (source, double.MinValue, (a, b) => {
1228 var v = selector (a); return v > b ? v : b;
1232 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1234 Check.SourceAndSelector (source, selector);
1236 return IterateNullable (source, float.MinValue, (a, b) => {
1237 var v = selector (a); return v > b ? v : b;
1241 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1243 Check.SourceAndSelector (source, selector);
1245 return IterateNullable (source, decimal.MinValue, (a, b) => {
1246 var v = selector (a); return v > b ? v : b;
1250 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1252 Check.SourceAndSelector (source, selector);
1254 bool notAssigned = true;
1255 TResult maximum = default (TResult);
1257 foreach (TSource item in source) {
1258 TResult element = selector (item);
1261 notAssigned = false;
1264 if (element is IComparable<TResult>)
1265 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1266 else if (element is System.IComparable)
1267 comparison = ((System.IComparable) element).CompareTo (maximum);
1269 throw new ArgumentNullException ();
1278 throw new InvalidOperationException ();
1287 public static int Min (this IEnumerable<int> source)
1289 Check.Source (source);
1291 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1294 public static long Min (this IEnumerable<long> source)
1296 Check.Source (source);
1298 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1301 public static double Min (this IEnumerable<double> source)
1303 Check.Source (source);
1305 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1308 public static float Min (this IEnumerable<float> source)
1310 Check.Source (source);
1312 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1315 public static decimal Min (this IEnumerable<decimal> source)
1317 Check.Source (source);
1319 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1322 public static int? Min (this IEnumerable<int?> source)
1324 Check.Source (source);
1326 return IterateNullable (source, int.MaxValue, (a, b) => a < b);
1329 public static long? Min (this IEnumerable<long?> source)
1331 Check.Source (source);
1333 return IterateNullable (source, long.MaxValue, (a, b) => a < b);
1336 public static double? Min (this IEnumerable<double?> source)
1338 Check.Source (source);
1340 return IterateNullable (source, double.MaxValue, (a, b) => a < b);
1343 public static float? Min (this IEnumerable<float?> source)
1345 Check.Source (source);
1347 return IterateNullable (source, float.MaxValue, (a, b) => a < b);
1350 public static decimal? Min (this IEnumerable<decimal?> source)
1352 Check.Source (source);
1354 return IterateNullable (source, decimal.MaxValue, (a, b) => a < b);
1357 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1359 Check.Source (source);
1361 bool notAssigned = true;
1362 TSource minimum = default (TSource);
1364 foreach (TSource element in source) {
1367 notAssigned = false;
1370 if (element is IComparable<TSource>)
1371 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1372 else if (element is System.IComparable)
1373 comparison = ((System.IComparable) element).CompareTo (minimum);
1375 throw new ArgumentNullException ();
1384 throw new InvalidOperationException ();
1389 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1391 Check.SourceAndSelector (source, selector);
1393 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1396 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1398 Check.SourceAndSelector (source, selector);
1400 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1403 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1405 Check.SourceAndSelector (source, selector);
1407 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1410 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1412 Check.SourceAndSelector (source, selector);
1414 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1417 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1419 Check.SourceAndSelector (source, selector);
1421 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1424 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1426 Check.SourceAndSelector (source, selector);
1428 return IterateNullable (source, int.MaxValue, (a, b) => {
1429 var v = selector (a); return v < b ? v : b;
1433 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1435 Check.SourceAndSelector (source, selector);
1437 return IterateNullable (source, long.MaxValue, (a, b) => {
1438 var v = selector (a); return v < b ? v : b;
1442 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1444 Check.SourceAndSelector (source, selector);
1446 return IterateNullable (source, float.MaxValue, (a, b) => {
1447 var v = selector (a); return v < b ? v : b;
1451 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1453 Check.SourceAndSelector (source, selector);
1455 return IterateNullable (source, double.MaxValue, (a, b) => {
1456 var v = selector (a); return v < b ? v : b;
1460 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1462 Check.SourceAndSelector (source, selector);
1464 return IterateNullable (source, decimal.MaxValue, (a, b) => {
1465 var v = selector (a); return v < b ? v : b;
1469 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1471 Check.SourceAndSelector (source, selector);
1473 bool notAssigned = true;
1474 TResult minimum = default (TResult);
1476 foreach (TSource item in source) {
1477 TResult element = selector (item);
1480 notAssigned = false;
1483 if (element is IComparable<TResult>)
1484 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1485 else if (element is System.IComparable)
1486 comparison = ((System.IComparable) element).CompareTo (minimum);
1488 throw new ArgumentNullException ();
1497 throw new InvalidOperationException ();
1506 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1508 Check.Source (source);
1510 return CreateOfTypeIterator<TResult> (source);
1513 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1515 foreach (object element in source)
1516 if (element is TResult)
1517 yield return (TResult) element;
1524 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1525 Func<TSource, TKey> keySelector)
1527 return OrderBy<TSource, TKey> (source, keySelector, null);
1530 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1531 Func<TSource, TKey> keySelector,
1532 IComparer<TKey> comparer)
1534 Check.SourceAndKeySelector (source, keySelector);
1536 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1541 #region OrderByDescending
1543 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1544 Func<TSource, TKey> keySelector)
1546 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1549 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1550 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1552 Check.SourceAndKeySelector (source, keySelector);
1554 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1561 public static IEnumerable<int> Range (int start, int count)
1564 throw new ArgumentOutOfRangeException ("count");
1566 long upto = ((long) start + count) - 1;
1568 if (upto > int.MaxValue)
1569 throw new ArgumentOutOfRangeException ();
1571 return CreateRangeIterator (start, (int) upto);
1574 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1576 for (int i = start; i <= upto; i++)
1584 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1587 throw new ArgumentOutOfRangeException ();
1589 return CreateRepeatIterator (element, count);
1592 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1594 for (int i = 0; i < count; i++)
1595 yield return element;
1602 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1604 Check.Source (source);
1606 var list = source as IList<TSource>;
1608 list = new List<TSource> (source);
1610 return CreateReverseIterator (list);
1613 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1615 for (int i = source.Count; i > 0; --i)
1616 yield return source [i - 1];
1623 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1625 Check.SourceAndSelector (source, selector);
1627 return CreateSelectIterator (source, selector);
1630 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1632 foreach (var element in source)
1633 yield return selector (element);
1636 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1638 Check.SourceAndSelector (source, selector);
1640 return CreateSelectIterator (source, selector);
1643 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1646 foreach (TSource element in source) {
1647 yield return selector (element, counter);
1656 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1658 Check.SourceAndSelector (source, selector);
1660 return CreateSelectManyIterator (source, selector);
1663 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1665 foreach (TSource element in source)
1666 foreach (TResult item in selector (element))
1670 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1672 Check.SourceAndSelector (source, selector);
1674 return CreateSelectManyIterator (source, selector);
1677 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1680 foreach (TSource element in source) {
1681 foreach (TResult item in selector (element, counter))
1687 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1688 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1690 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1692 return CreateSelectManyIterator (source, collectionSelector, selector);
1695 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1696 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1698 foreach (TSource element in source)
1699 foreach (TCollection collection in collectionSelector (element))
1700 yield return selector (element, collection);
1703 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1704 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1706 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1708 return CreateSelectManyIterator (source, collectionSelector, selector);
1711 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1712 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1715 foreach (TSource element in source)
1716 foreach (TCollection collection in collectionSelector (element, counter++))
1717 yield return selector (element, collection);
1724 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1727 var item = default (TSource);
1729 foreach (var element in source) {
1730 if (!predicate (element))
1734 throw new InvalidOperationException ();
1740 if (!found && fallback == Fallback.Throw)
1741 throw new InvalidOperationException ();
1746 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1748 Check.Source (source);
1750 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1753 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1755 Check.SourceAndPredicate (source, predicate);
1757 return source.Single (predicate, Fallback.Throw);
1762 #region SingleOrDefault
1764 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1766 Check.Source (source);
1768 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1771 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1773 Check.SourceAndPredicate (source, predicate);
1775 return source.Single (predicate, Fallback.Default);
1782 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1784 Check.Source (source);
1786 return CreateSkipIterator (source, count);
1789 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1792 foreach (var element in source) {
1796 yield return element;
1804 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1806 Check.SourceAndPredicate (source, predicate);
1808 return CreateSkipWhileIterator (source, predicate);
1811 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1815 foreach (TSource element in source) {
1817 yield return element;
1819 if (!predicate (element)) {
1820 yield return element;
1826 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1828 Check.SourceAndPredicate (source, predicate);
1830 return CreateSkipWhileIterator (source, predicate);
1833 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1838 foreach (TSource element in source) {
1840 yield return element;
1842 if (!predicate (element, counter)) {
1843 yield return element;
1854 public static int Sum (this IEnumerable<int> source)
1856 Check.Source (source);
1858 return Sum<int, int> (source, (a, b) => checked (a + b));
1861 public static int? Sum (this IEnumerable<int?> source)
1863 Check.Source (source);
1865 return source.SumNullable<int?, int?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1868 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1870 Check.SourceAndSelector (source, selector);
1872 return Sum<TSource, int> (source, (a, b) => checked (a + selector (b)));
1875 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1877 Check.SourceAndSelector (source, selector);
1879 return source.SumNullable<TSource, int?> (0, (a, b) => {
1880 var value = selector (b);
1881 return value.HasValue ? checked (a + value.Value) : a;
1885 public static long Sum (this IEnumerable<long> source)
1887 Check.Source (source);
1889 return Sum<long, long> (source, (a, b) => checked (a + b));
1892 public static long? Sum (this IEnumerable<long?> source)
1894 Check.Source (source);
1896 return source.SumNullable<long?, long?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1899 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1901 Check.SourceAndSelector (source, selector);
1903 return Sum<TSource, long> (source, (a, b) => checked (a + selector (b)));
1906 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1908 Check.SourceAndSelector (source, selector);
1910 return source.SumNullable<TSource, long?> (0, (a, b) => {
1911 var value = selector (b);
1912 return value.HasValue ? checked (a + value.Value) : a;
1916 public static double Sum (this IEnumerable<double> source)
1918 Check.Source (source);
1920 return Sum<double, double> (source, (a, b) => checked (a + b));
1923 public static double? Sum (this IEnumerable<double?> source)
1925 Check.Source (source);
1927 return source.SumNullable<double?, double?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1930 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1932 Check.SourceAndSelector (source, selector);
1934 return Sum<TSource, double> (source, (a, b) => checked (a + selector (b)));
1937 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1939 Check.SourceAndSelector (source, selector);
1941 return source.SumNullable<TSource, double?> (0, (a, b) => {
1942 var value = selector (b);
1943 return value.HasValue ? checked (a + value.Value) : a;
1947 public static float Sum (this IEnumerable<float> source)
1949 Check.Source (source);
1951 return Sum<float, float> (source, (a, b) => checked (a + b));
1954 public static float? Sum (this IEnumerable<float?> source)
1956 Check.Source (source);
1958 return source.SumNullable<float?, float?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1961 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1963 Check.SourceAndSelector (source, selector);
1965 return Sum<TSource, float> (source, (a, b) => checked (a + selector (b)));
1968 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1970 Check.SourceAndSelector (source, selector);
1972 return source.SumNullable<TSource, float?> (0, (a, b) => {
1973 var value = selector (b);
1974 return value.HasValue ? checked (a + value.Value) : a;
1978 public static decimal Sum (this IEnumerable<decimal> source)
1980 Check.Source (source);
1982 return Sum<decimal, decimal> (source, (a, b) => checked (a + b));
1985 public static decimal? Sum (this IEnumerable<decimal?> source)
1987 Check.Source (source);
1989 return source.SumNullable<decimal?, decimal?> (0, (total, element) => element.HasValue ? checked (total + element) : total);
1992 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1994 Check.SourceAndSelector (source, selector);
1996 return Sum<TSource, decimal> (source, (a, b) => checked (a + selector (b)));
1999 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
2001 Check.SourceAndSelector (source, selector);
2003 return source.SumNullable<TSource, decimal?> (0, (a, b) => {
2004 var value = selector (b);
2005 return value.HasValue ? checked (a + value.Value) : a;
2009 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
2011 TR total = default (TR);
2013 foreach (var element in source) {
2014 total = selector (total, element);
2021 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, TR zero, Func<TR, TA, TR> selector)
2024 foreach (var element in source) {
2025 total = selector (total, element);
2035 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2037 Check.Source (source);
2039 return CreateTakeIterator (source, count);
2042 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2048 foreach (TSource element in source) {
2049 yield return element;
2051 if (++counter == count)
2060 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2062 Check.SourceAndPredicate (source, predicate);
2064 return CreateTakeWhileIterator (source, predicate);
2067 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2069 foreach (var element in source) {
2070 if (!predicate (element))
2073 yield return element;
2077 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2079 Check.SourceAndPredicate (source, predicate);
2081 return CreateTakeWhileIterator (source, predicate);
2084 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2087 foreach (var element in source) {
2088 if (!predicate (element, counter))
2091 yield return element;
2100 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2102 return ThenBy<TSource, TKey> (source, keySelector, null);
2105 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2106 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2108 Check.SourceAndKeySelector (source, keySelector);
2110 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2115 #region ThenByDescending
2117 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2118 Func<TSource, TKey> keySelector)
2120 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2123 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2124 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2126 Check.SourceAndKeySelector (source, keySelector);
2128 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2135 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2137 Check.Source (source);
2139 var collection = source as ICollection<TSource>;
2140 if (collection != null) {
2141 var array = new TSource [collection.Count];
2142 collection.CopyTo (array, 0);
2146 return new List<TSource> (source).ToArray ();
2151 #region ToDictionary
2152 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2153 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2155 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2158 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2159 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2161 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2163 if (comparer == null)
2164 comparer = EqualityComparer<TKey>.Default;
2166 var dict = new Dictionary<TKey, TElement> (comparer);
2167 foreach (var e in source)
2168 dict.Add (keySelector (e), elementSelector (e));
2173 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2174 Func<TSource, TKey> keySelector)
2176 return ToDictionary (source, keySelector, null);
2179 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2180 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2182 return ToDictionary<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
2188 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2190 Check.Source (source);
2192 return new List<TSource> (source);
2198 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2200 return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, null);
2203 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2204 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2206 return ToLookup<TSource, TKey, TSource> (source, keySelector, element => element, comparer);
2209 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2210 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2212 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2215 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2216 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2218 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2220 var dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2221 foreach (var element in source) {
2222 var key = keySelector (element);
2224 throw new ArgumentNullException ("key");
2226 List<TElement> list;
2227 if (!dictionary.TryGetValue (key, out list)) {
2228 list = new List<TElement> ();
2229 dictionary.Add (key, list);
2232 list.Add (elementSelector (element));
2235 return new Lookup<TKey, TElement> (dictionary);
2240 #region SequenceEqual
2242 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2244 return first.SequenceEqual (second, null);
2247 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2249 Check.FirstAndSecond (first, second);
2251 if (comparer == null)
2252 comparer = EqualityComparer<TSource>.Default;
2254 using (IEnumerator<TSource> first_enumerator = first.GetEnumerator (),
2255 second_enumerator = second.GetEnumerator ()) {
2257 while (first_enumerator.MoveNext ()) {
2258 if (!second_enumerator.MoveNext ())
2261 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2265 return !second_enumerator.MoveNext ();
2273 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2275 Check.FirstAndSecond (first, second);
2277 return first.Union (second, null);
2280 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2282 Check.FirstAndSecond (first, second);
2284 if (comparer == null)
2285 comparer = EqualityComparer<TSource>.Default;
2287 return CreateUnionIterator (first, second, comparer);
2290 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2292 var items = new HashSet<TSource> (comparer);
2293 foreach (var element in first) {
2294 if (! items.Contains (element)) {
2295 items.Add (element);
2296 yield return element;
2300 foreach (var element in second) {
2301 if (! items.Contains (element, comparer)) {
2302 items.Add (element);
2303 yield return element;
2312 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2314 Check.SourceAndPredicate (source, predicate);
2316 return CreateWhereIterator (source, predicate);
2319 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2321 foreach (TSource element in source)
2322 if (predicate (element))
2323 yield return element;
2326 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2328 Check.SourceAndPredicate (source, predicate);
2330 return CreateWhereIterator (source, predicate);
2333 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2336 foreach (TSource element in source) {
2337 if (predicate (element, counter))
2338 yield return element;
2345 class ReadOnlyCollectionOf<T> {
2346 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2349 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2352 return ReadOnlyCollectionOf<TSource>.Empty;
2354 var ro = source as ReadOnlyCollection<TSource>;
2358 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());