2008-09-30 Michael Hutchinson <mhutchinson@novell.com>
[mono-project.git] / mcs / class / System.Core / System.Linq / Enumerable.cs
blobfce64ba05c2ad58d0ce17741e0480db39634cfce
1 //
2 // Enumerable.cs
3 //
4 // Authors:
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)
9 //
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
34 using System;
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Collections.ObjectModel;
39 namespace System.Linq
41 public static class Enumerable
43 enum Fallback {
44 Default,
45 Throw
48 class PredicateOf<T> {
49 public static readonly Func<T, bool> Always = (t) => true;
52 #region Aggregate
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);
67 return folded;
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);
80 return folded;
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");
89 var result = seed;
90 foreach (var e in source)
91 result = func (result, e);
93 return resultSelector (result);
96 #endregion
98 #region All
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))
106 return false;
108 return true;
111 #endregion
113 #region Any
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))
129 return true;
131 return false;
134 #endregion
136 #region AsEnumerable
138 public static IEnumerable<TSource> AsEnumerable<TSource> (this IEnumerable<TSource> source)
140 return source;
143 #endregion
145 #region Average
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);
181 long counter = 0;
182 foreach (var element in source) {
183 total = func (total, element);
184 ++counter;
187 if (counter == 0)
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);
202 long counter = 0;
203 foreach (var element in source) {
204 if (!element.HasValue)
205 continue;
207 total = func (total, element.Value);
208 counter++;
211 if (counter == 0)
212 return null;
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);
322 #endregion
324 #region Cast
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;
339 #endregion
341 #region Concat
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;
358 #endregion
360 #region Contains
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))
380 return true;
382 return false;
384 #endregion
386 #region Count
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;
396 int counter = 0;
397 using (var enumerator = source.GetEnumerator ())
398 while (enumerator.MoveNext ())
399 counter++;
401 return counter;
404 public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
406 Check.SourceAndSelector (source, selector);
408 int counter = 0;
409 foreach (var element in source)
410 if (selector (element))
411 counter++;
413 return counter;
416 #endregion
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)
434 bool empty = true;
435 foreach (TSource item in source) {
436 empty = false;
437 yield return item;
440 if (empty)
441 yield return defaultValue;
444 #endregion
446 #region Distinct
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)) {
468 items.Add (element);
469 yield return element;
474 #endregion
476 #region ElementAt
478 static TSource ElementAt<TSource> (this IEnumerable<TSource> source, int index, Fallback fallback)
480 long counter = 0L;
482 foreach (var element in source) {
483 if (index == counter++)
484 return element;
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);
497 if (index < 0)
498 throw new ArgumentOutOfRangeException ();
500 var list = source as IList<TSource>;
501 if (list != null)
502 return list [index];
504 return source.ElementAt (index, Fallback.Throw);
507 #endregion
509 #region ElementAtOrDefault
511 public static TSource ElementAtOrDefault<TSource> (this IEnumerable<TSource> source, int index)
513 Check.Source (source);
515 if (index < 0)
516 return default (TSource);
518 var list = source as IList<TSource>;
519 if (list != null)
520 return index < list.Count ? list [index] : default (TSource);
522 return source.ElementAt (index, Fallback.Default);
525 #endregion
527 #region Empty
529 public static IEnumerable<TResult> Empty<TResult> ()
531 return new TResult [0];
534 #endregion
536 #region Except
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;
562 #endregion
564 #region First
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))
570 return 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 return source.First (PredicateOf<TSource>.Always, Fallback.Throw);
585 public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
587 Check.SourceAndPredicate (source, predicate);
589 return source.First (predicate, Fallback.Throw);
592 #endregion
594 #region FirstOrDefault
596 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source)
598 Check.Source (source);
600 return source.First (PredicateOf<TSource>.Always, Fallback.Default);
603 public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
605 Check.SourceAndPredicate (source, predicate);
607 return source.First (predicate, Fallback.Default);
610 #endregion
612 #region GroupBy
614 private static List<T> ContainsGroup<K, T> (
615 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)
617 IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);
618 foreach (KeyValuePair<K, List<T>> value in items) {
619 if (comparerInUse.Equals (value.Key, key))
620 return value.Value;
622 return null;
625 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
626 Func<TSource, TKey> keySelector)
628 return GroupBy<TSource, TKey> (source, keySelector, null);
631 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey> (this IEnumerable<TSource> source,
632 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
634 Check.SourceAndKeySelector (source, keySelector);
636 return CreateGroupByIterator (source, keySelector, comparer);
639 static IEnumerable<IGrouping<TKey, TSource>> CreateGroupByIterator<TSource, TKey> (this IEnumerable<TSource> source,
640 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
642 Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>> ();
643 List<TSource> nullList = new List<TSource> ();
644 int counter = 0;
645 int nullCounter = -1;
647 foreach (TSource element in source) {
648 TKey key = keySelector (element);
649 if (key == null) {
650 nullList.Add (element);
651 if (nullCounter == -1) {
652 nullCounter = counter;
653 counter++;
655 } else {
656 List<TSource> group = ContainsGroup<TKey, TSource> (groups, key, comparer);
657 if (group == null) {
658 group = new List<TSource> ();
659 groups.Add (key, group);
660 counter++;
662 group.Add (element);
666 counter = 0;
667 foreach (KeyValuePair<TKey, List<TSource>> group in groups) {
668 if (counter == nullCounter) {
669 Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource> (default (TKey), nullList);
670 yield return nullGroup;
671 counter++;
673 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource> (group.Key, group.Value);
674 yield return grouping;
675 counter++;
679 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
680 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
682 return GroupBy<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
685 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement> (this IEnumerable<TSource> source,
686 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
688 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
690 Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>> ();
691 List<TElement> nullList = new List<TElement> ();
692 int counter = 0;
693 int nullCounter = -1;
695 foreach (TSource item in source) {
696 TKey key = keySelector (item);
697 TElement element = elementSelector (item);
698 if (key == null) {
699 nullList.Add (element);
700 if (nullCounter == -1) {
701 nullCounter = counter;
702 counter++;
704 } else {
705 List<TElement> group = ContainsGroup<TKey, TElement> (groups, key, comparer);
706 if (group == null) {
707 group = new List<TElement> ();
708 groups.Add (key, group);
709 counter++;
711 group.Add (element);
715 counter = 0;
716 foreach (KeyValuePair<TKey, List<TElement>> group in groups) {
717 if (counter == nullCounter) {
718 Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement> (default (TKey), nullList);
719 yield return nullGroup;
720 counter++;
722 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement> (group.Key, group.Value);
723 yield return grouping;
724 counter++;
728 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
729 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
730 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
732 return GroupBy (source, keySelector, elementSelector, resultSelector, null);
735 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult> (this IEnumerable<TSource> source,
736 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector,
737 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
738 IEqualityComparer<TKey> comparer)
740 IEnumerable<IGrouping<TKey, TElement>> groups = GroupBy<TSource, TKey, TElement> (
741 source, keySelector, elementSelector, comparer);
743 foreach (IGrouping<TKey, TElement> group in groups)
744 yield return resultSelector (group.Key, group);
747 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
748 Func<TSource, TKey> keySelector,
749 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
751 return GroupBy (source, keySelector, resultSelector, null);
754 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult> (this IEnumerable<TSource> source,
755 Func<TSource, TKey> keySelector,
756 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
757 IEqualityComparer<TKey> comparer)
759 IEnumerable<IGrouping<TKey,TSource>> groups = GroupBy<TSource, TKey> (source, keySelector, comparer);
761 foreach (IGrouping<TKey, TSource> group in groups)
762 yield return resultSelector (group.Key, group);
765 #endregion
767 # region GroupJoin
769 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
770 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
771 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
773 return GroupJoin (outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
776 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
777 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
778 Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
779 IEqualityComparer<TKey> comparer)
781 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
783 if (comparer == null)
784 comparer = EqualityComparer<TKey>.Default;
786 return CreateGroupJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
789 static IEnumerable<TResult> CreateGroupJoinIterator<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 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
795 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
796 foreach (U element in inner)
798 K innerKey = innerKeySelector (element);
799 if (!innerKeys.ContainsKey (innerKey))
800 innerKeys.Add (innerKey, new List<U> ());
801 innerKeys[innerKey].Add (element);
804 foreach (TOuter element in outer) {
805 TKey outerKey = outerKeySelector (element);
806 if (innerKeys.Contains (outerKey))
807 yield return resultSelector (element, innerKeys [outerKey]);
808 else
809 yield return resultSelector (element, Empty<TInner> ());
813 #endregion
815 #region Intersect
817 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
819 return Intersect (first, second, null);
822 public static IEnumerable<TSource> Intersect<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
824 Check.FirstAndSecond (first, second);
826 if (comparer == null)
827 comparer = EqualityComparer<TSource>.Default;
829 return CreateIntersectIterator (first, second, comparer);
832 static IEnumerable<TSource> CreateIntersectIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
834 var items = new HashSet<TSource> (second, comparer);
835 foreach (TSource element in first) {
836 if (items.Contains (element))
837 yield return element;
841 #endregion
843 # region Join
845 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
846 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
847 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
849 Check.JoinSelectors (outer, inner, outerKeySelector, innerKeySelector, resultSelector);
851 if (comparer == null)
852 comparer = EqualityComparer<TKey>.Default;
854 return CreateJoinIterator (outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
857 static IEnumerable<TResult> CreateJoinIterator<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
858 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
859 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
861 ILookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey> (inner, innerKeySelector, comparer);
862 /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();
863 foreach (U element in inner)
865 K innerKey = innerKeySelector (element);
866 if (!innerKeys.ContainsKey (innerKey))
867 innerKeys.Add (innerKey, new List<U> ());
868 innerKeys[innerKey].Add (element);
871 foreach (TOuter element in outer) {
872 TKey outerKey = outerKeySelector (element);
873 if (innerKeys.Contains (outerKey)) {
874 foreach (TInner innerElement in innerKeys [outerKey])
875 yield return resultSelector (element, innerElement);
880 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> (this IEnumerable<TOuter> outer,
881 IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,
882 Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)
884 return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, null);
887 #endregion
889 #region Last
891 static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
893 var empty = true;
894 var item = default (TSource);
896 foreach (var element in source) {
897 if (!predicate (element))
898 continue;
900 item = element;
901 empty = false;
904 if (!empty)
905 return item;
907 if (fallback == Fallback.Throw)
908 throw new InvalidOperationException ();
910 return item;
913 public static TSource Last<TSource> (this IEnumerable<TSource> source)
915 Check.Source (source);
917 return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
920 public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
922 Check.SourceAndPredicate (source, predicate);
924 return source.Last (predicate, Fallback.Throw);
927 #endregion
929 #region LastOrDefault
931 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source)
933 Check.Source (source);
935 var list = source as IList<TSource>;
936 if (list != null)
937 return list.Count > 0 ? list [list.Count - 1] : default (TSource);
939 return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
942 public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
944 Check.SourceAndPredicate (source, predicate);
946 return source.Last (predicate, Fallback.Default);
949 #endregion
951 #region LongCount
953 public static long LongCount<TSource> (this IEnumerable<TSource> source)
955 Check.Source (source);
957 #if !NET_2_1
958 var array = source as TSource [];
959 if (array != null)
960 return array.LongLength;
961 #endif
963 long counter = 0;
964 using (var enumerator = source.GetEnumerator ())
965 while (enumerator.MoveNext ())
966 counter++;
968 return counter;
971 public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
973 Check.SourceAndSelector (source, selector);
975 long counter = 0;
976 foreach (TSource element in source)
977 if (selector (element))
978 counter++;
980 return counter;
983 #endregion
985 #region Max
987 public static int Max (this IEnumerable<int> source)
989 Check.Source (source);
991 return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b));
994 public static long Max (this IEnumerable<long> source)
996 Check.Source (source);
998 return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b));
1001 public static double Max (this IEnumerable<double> source)
1003 Check.Source (source);
1005 return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b));
1008 public static float Max (this IEnumerable<float> source)
1010 Check.Source (source);
1012 return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b));
1015 public static decimal Max (this IEnumerable<decimal> source)
1017 Check.Source (source);
1019 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b));
1022 public static int? Max (this IEnumerable<int?> source)
1024 Check.Source (source);
1026 return IterateNullable (source, int.MinValue, (a, b) => a > b);
1029 public static long? Max (this IEnumerable<long?> source)
1031 Check.Source (source);
1033 return IterateNullable (source, long.MinValue, (a, b) => a > b);
1036 public static double? Max (this IEnumerable<double?> source)
1038 Check.Source (source);
1040 return IterateNullable (source, double.MinValue, (a, b) => a > b);
1043 public static float? Max (this IEnumerable<float?> source)
1045 Check.Source (source);
1047 return IterateNullable (source, float.MinValue, (a, b) => a > b);
1050 public static decimal? Max (this IEnumerable<decimal?> source)
1052 Check.Source (source);
1054 return IterateNullable (source, decimal.MinValue, (a, b) => a > b);
1057 static T? IterateNullable<T> (IEnumerable<T?> source, T initValue, Func<T?, T?, bool> selector) where T : struct
1059 int counter = 0;
1060 T? value = initValue;
1061 foreach (var element in source) {
1062 if (!element.HasValue)
1063 continue;
1065 if (selector (element.Value, value))
1066 value = element;
1067 ++counter;
1070 if (counter == 0)
1071 return null;
1073 return value;
1076 public static TSource Max<TSource> (this IEnumerable<TSource> source)
1078 Check.Source (source);
1080 bool notAssigned = true;
1081 TSource maximum = default (TSource);
1082 int counter = 0;
1083 foreach (TSource element in source) {
1084 if (notAssigned) {
1085 maximum = element;
1086 notAssigned = false;
1087 } else {
1088 int comparison;
1089 if (element is IComparable<TSource>)
1090 comparison = ((IComparable<TSource>) element).CompareTo (maximum);
1091 else if (element is System.IComparable)
1092 comparison = ((System.IComparable) element).CompareTo (maximum);
1093 else
1094 throw new ArgumentNullException ();
1096 if (comparison > 0)
1097 maximum = element;
1099 counter++;
1102 if (counter == 0)
1103 throw new InvalidOperationException ();
1104 else
1105 return maximum;
1108 public static int Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1110 Check.SourceAndSelector (source, selector);
1112 return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b));
1115 public static long Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1117 Check.SourceAndSelector (source, selector);
1119 return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b));
1122 public static double Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1124 Check.SourceAndSelector (source, selector);
1126 return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b));
1129 public static float Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1131 Check.SourceAndSelector (source, selector);
1133 return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b));
1136 public static decimal Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1138 Check.SourceAndSelector (source, selector);
1140 return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b));
1143 static U Iterate<T, U> (IEnumerable<T> source, U initValue, Func<T, U, U> selector)
1145 int counter = 0;
1146 foreach (var element in source) {
1147 initValue = selector (element, initValue);
1148 ++counter;
1151 if (counter == 0)
1152 throw new InvalidOperationException ();
1154 return initValue;
1157 static U? IterateNullable<T, U> (IEnumerable<T> source, U initialValue, Func<T, U?, U?> selector) where U : struct
1159 int counter = 0;
1160 U? value = initialValue;
1161 foreach (var element in source) {
1162 value = selector (element, value);
1163 if (!value.HasValue)
1164 continue;
1166 ++counter;
1169 if (counter == 0)
1170 return null;
1172 return value;
1175 public static int? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1177 Check.SourceAndSelector (source, selector);
1179 return IterateNullable (source, int.MinValue, (a, b) => {
1180 var v = selector (a); return v > b ? v : b;
1184 public static long? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1186 Check.SourceAndSelector (source, selector);
1188 return IterateNullable (source, long.MinValue, (a, b) => {
1189 var v = selector (a); return v > b ? v : b;
1193 public static double? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1195 Check.SourceAndSelector (source, selector);
1197 return IterateNullable (source, double.MinValue, (a, b) => {
1198 var v = selector (a); return v > b ? v : b;
1202 public static float? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1204 Check.SourceAndSelector (source, selector);
1206 return IterateNullable (source, float.MinValue, (a, b) => {
1207 var v = selector (a); return v > b ? v : b;
1211 public static decimal? Max<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1213 Check.SourceAndSelector (source, selector);
1215 return IterateNullable (source, decimal.MinValue, (a, b) => {
1216 var v = selector (a); return v > b ? v : b;
1220 public static TResult Max<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1222 Check.SourceAndSelector (source, selector);
1224 bool notAssigned = true;
1225 TResult maximum = default (TResult);
1226 int counter = 0;
1227 foreach (TSource item in source) {
1228 TResult element = selector (item);
1229 if (notAssigned) {
1230 maximum = element;
1231 notAssigned = false;
1232 } else {
1233 int comparison;
1234 if (element is IComparable<TResult>)
1235 comparison = ((IComparable<TResult>) element).CompareTo (maximum);
1236 else if (element is System.IComparable)
1237 comparison = ((System.IComparable) element).CompareTo (maximum);
1238 else
1239 throw new ArgumentNullException ();
1241 if (comparison > 0)
1242 maximum = element;
1244 counter++;
1247 if (counter == 0)
1248 throw new InvalidOperationException ();
1249 else
1250 return maximum;
1253 #endregion
1255 #region Min
1257 public static int Min (this IEnumerable<int> source)
1259 Check.Source (source);
1261 return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b));
1264 public static long Min (this IEnumerable<long> source)
1266 Check.Source (source);
1268 return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b));
1271 public static double Min (this IEnumerable<double> source)
1273 Check.Source (source);
1275 return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b));
1278 public static float Min (this IEnumerable<float> source)
1280 Check.Source (source);
1282 return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b));
1285 public static decimal Min (this IEnumerable<decimal> source)
1287 Check.Source (source);
1289 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b));
1292 public static int? Min (this IEnumerable<int?> source)
1294 Check.Source (source);
1296 return IterateNullable (source, int.MaxValue, (a, b) => a < b);
1299 public static long? Min (this IEnumerable<long?> source)
1301 Check.Source (source);
1303 return IterateNullable (source, long.MaxValue, (a, b) => a < b);
1306 public static double? Min (this IEnumerable<double?> source)
1308 Check.Source (source);
1310 return IterateNullable (source, double.MaxValue, (a, b) => a < b);
1313 public static float? Min (this IEnumerable<float?> source)
1315 Check.Source (source);
1317 return IterateNullable (source, float.MaxValue, (a, b) => a < b);
1320 public static decimal? Min (this IEnumerable<decimal?> source)
1322 Check.Source (source);
1324 return IterateNullable (source, decimal.MaxValue, (a, b) => a < b);
1327 public static TSource Min<TSource> (this IEnumerable<TSource> source)
1329 Check.Source (source);
1331 bool notAssigned = true;
1332 TSource minimum = default (TSource);
1333 int counter = 0;
1334 foreach (TSource element in source) {
1335 if (notAssigned) {
1336 minimum = element;
1337 notAssigned = false;
1338 } else {
1339 int comparison;
1340 if (element is IComparable<TSource>)
1341 comparison = ((IComparable<TSource>) element).CompareTo (minimum);
1342 else if (element is System.IComparable)
1343 comparison = ((System.IComparable) element).CompareTo (minimum);
1344 else
1345 throw new ArgumentNullException ();
1347 if (comparison < 0)
1348 minimum = element;
1350 counter++;
1353 if (counter == 0)
1354 throw new InvalidOperationException ();
1355 else
1356 return minimum;
1359 public static int Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1361 Check.SourceAndSelector (source, selector);
1363 return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b));
1366 public static long Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1368 Check.SourceAndSelector (source, selector);
1370 return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b));
1373 public static double Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1375 Check.SourceAndSelector (source, selector);
1377 return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b));
1380 public static float Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1382 Check.SourceAndSelector (source, selector);
1384 return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b));
1387 public static decimal Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1389 Check.SourceAndSelector (source, selector);
1391 return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b));
1394 public static int? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1396 Check.SourceAndSelector (source, selector);
1398 return IterateNullable (source, int.MaxValue, (a, b) => {
1399 var v = selector (a); return v < b ? v : b;
1403 public static long? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1405 Check.SourceAndSelector (source, selector);
1407 return IterateNullable (source, long.MaxValue, (a, b) => {
1408 var v = selector (a); return v < b ? v : b;
1412 public static float? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1414 Check.SourceAndSelector (source, selector);
1416 return IterateNullable (source, float.MaxValue, (a, b) => {
1417 var v = selector (a); return v < b ? v : b;
1421 public static double? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1423 Check.SourceAndSelector (source, selector);
1425 return IterateNullable (source, double.MaxValue, (a, b) => {
1426 var v = selector (a); return v < b ? v : b;
1430 public static decimal? Min<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1432 Check.SourceAndSelector (source, selector);
1434 return IterateNullable (source, decimal.MaxValue, (a, b) => {
1435 var v = selector (a); return v < b ? v : b;
1439 public static TResult Min<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1441 Check.SourceAndSelector (source, selector);
1443 bool notAssigned = true;
1444 TResult minimum = default (TResult);
1445 int counter = 0;
1446 foreach (TSource item in source) {
1447 TResult element = selector (item);
1448 if (notAssigned) {
1449 minimum = element;
1450 notAssigned = false;
1451 } else {
1452 int comparison;
1453 if (element is IComparable<TResult>)
1454 comparison = ((IComparable<TResult>) element).CompareTo (minimum);
1455 else if (element is System.IComparable)
1456 comparison = ((System.IComparable) element).CompareTo (minimum);
1457 else
1458 throw new ArgumentNullException ();
1460 if (comparison < 0)
1461 minimum = element;
1463 counter++;
1466 if (counter == 0)
1467 throw new InvalidOperationException ();
1468 else
1469 return minimum;
1472 #endregion
1474 #region OfType
1476 public static IEnumerable<TResult> OfType<TResult> (this IEnumerable source)
1478 Check.Source (source);
1480 return CreateOfTypeIterator<TResult> (source);
1483 static IEnumerable<TResult> CreateOfTypeIterator<TResult> (IEnumerable source)
1485 foreach (object element in source)
1486 if (element is TResult)
1487 yield return (TResult) element;
1490 #endregion
1492 #region OrderBy
1494 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1495 Func<TSource, TKey> keySelector)
1497 return OrderBy<TSource, TKey> (source, keySelector, null);
1500 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
1501 Func<TSource, TKey> keySelector,
1502 IComparer<TKey> comparer)
1504 Check.SourceAndKeySelector (source, keySelector);
1506 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Ascending);
1509 #endregion
1511 #region OrderByDescending
1513 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1514 Func<TSource, TKey> keySelector)
1516 return OrderByDescending<TSource, TKey> (source, keySelector, null);
1519 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
1520 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
1522 Check.SourceAndKeySelector (source, keySelector);
1524 return new OrderedSequence<TSource, TKey> (source, keySelector, comparer, SortDirection.Descending);
1527 #endregion
1529 #region Range
1531 public static IEnumerable<int> Range (int start, int count)
1533 if (count < 0)
1534 throw new ArgumentOutOfRangeException ("count");
1536 long upto = ((long) start + count) - 1;
1538 if (upto > int.MaxValue)
1539 throw new ArgumentOutOfRangeException ();
1541 return CreateRangeIterator (start, (int) upto);
1544 static IEnumerable<int> CreateRangeIterator (int start, int upto)
1546 for (int i = start; i <= upto; i++)
1547 yield return i;
1550 #endregion
1552 #region Repeat
1554 public static IEnumerable<TResult> Repeat<TResult> (TResult element, int count)
1556 if (count < 0)
1557 throw new ArgumentOutOfRangeException ();
1559 return CreateRepeatIterator (element, count);
1562 static IEnumerable<TResult> CreateRepeatIterator<TResult> (TResult element, int count)
1564 for (int i = 0; i < count; i++)
1565 yield return element;
1568 #endregion
1570 #region Reverse
1572 public static IEnumerable<TSource> Reverse<TSource> (this IEnumerable<TSource> source)
1574 Check.Source (source);
1576 var list = source as IList<TSource>;
1577 if (list == null)
1578 list = new List<TSource> (source);
1580 return CreateReverseIterator (list);
1583 static IEnumerable<TSource> CreateReverseIterator<TSource> (IList<TSource> source)
1585 for (int i = source.Count; i > 0; --i)
1586 yield return source [i - 1];
1589 #endregion
1591 #region Select
1593 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, TResult> selector)
1595 Check.SourceAndSelector (source, selector);
1597 return CreateSelectIterator (source, selector);
1600 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, TResult> selector)
1602 foreach (var element in source)
1603 yield return selector (element);
1606 public static IEnumerable<TResult> Select<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1608 Check.SourceAndSelector (source, selector);
1610 return CreateSelectIterator (source, selector);
1613 static IEnumerable<TResult> CreateSelectIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
1615 int counter = 0;
1616 foreach (TSource element in source) {
1617 yield return selector (element, counter);
1618 counter++;
1622 #endregion
1624 #region SelectMany
1626 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1628 Check.SourceAndSelector (source, selector);
1630 return CreateSelectManyIterator (source, selector);
1633 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
1635 foreach (TSource element in source)
1636 foreach (TResult item in selector (element))
1637 yield return item;
1640 public static IEnumerable<TResult> SelectMany<TSource, TResult> (this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1642 Check.SourceAndSelector (source, selector);
1644 return CreateSelectManyIterator (source, selector);
1647 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult> (IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
1649 int counter = 0;
1650 foreach (TSource element in source) {
1651 foreach (TResult item in selector (element, counter))
1652 yield return item;
1653 counter++;
1657 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1658 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1660 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1662 return CreateSelectManyIterator (source, collectionSelector, selector);
1665 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1666 Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1668 foreach (TSource element in source)
1669 foreach (TCollection collection in collectionSelector (element))
1670 yield return selector (element, collection);
1673 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
1674 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1676 Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
1678 return CreateSelectManyIterator (source, collectionSelector, selector);
1681 static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
1682 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
1684 int counter = 0;
1685 foreach (TSource element in source)
1686 foreach (TCollection collection in collectionSelector (element, counter++))
1687 yield return selector (element, collection);
1690 #endregion
1692 #region Single
1694 static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
1696 var found = false;
1697 var item = default (TSource);
1699 foreach (var element in source) {
1700 if (!predicate (element))
1701 continue;
1703 if (found)
1704 throw new InvalidOperationException ();
1706 found = true;
1707 item = element;
1710 if (!found && fallback == Fallback.Throw)
1711 throw new InvalidOperationException ();
1713 return item;
1716 public static TSource Single<TSource> (this IEnumerable<TSource> source)
1718 Check.Source (source);
1720 return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
1723 public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1725 Check.SourceAndPredicate (source, predicate);
1727 return source.Single (predicate, Fallback.Throw);
1730 #endregion
1732 #region SingleOrDefault
1734 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source)
1736 Check.Source (source);
1738 return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
1741 public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1743 Check.SourceAndPredicate (source, predicate);
1745 return source.Single (predicate, Fallback.Default);
1748 #endregion
1750 #region Skip
1752 public static IEnumerable<TSource> Skip<TSource> (this IEnumerable<TSource> source, int count)
1754 Check.Source (source);
1756 return CreateSkipIterator (source, count);
1759 static IEnumerable<TSource> CreateSkipIterator<TSource> (IEnumerable<TSource> source, int count)
1761 int i = 0;
1762 foreach (var element in source) {
1763 if (i++ < count)
1764 continue;
1766 yield return element;
1770 #endregion
1772 #region SkipWhile
1774 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
1776 Check.SourceAndPredicate (source, predicate);
1778 return CreateSkipWhileIterator (source, predicate);
1781 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
1783 bool yield = false;
1785 foreach (TSource element in source) {
1786 if (yield)
1787 yield return element;
1788 else
1789 if (!predicate (element)) {
1790 yield return element;
1791 yield = true;
1796 public static IEnumerable<TSource> SkipWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1798 Check.SourceAndPredicate (source, predicate);
1800 return CreateSkipWhileIterator (source, predicate);
1803 static IEnumerable<TSource> CreateSkipWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
1805 int counter = 0;
1806 bool yield = false;
1808 foreach (TSource element in source) {
1809 if (yield)
1810 yield return element;
1811 else
1812 if (!predicate (element, counter)) {
1813 yield return element;
1814 yield = true;
1816 counter++;
1820 #endregion
1822 #region Sum
1824 public static int Sum (this IEnumerable<int> source)
1826 Check.Source (source);
1828 return Sum<int, int> (source, (a, b) => a + b);
1831 public static int? Sum (this IEnumerable<int?> source)
1833 Check.Source (source);
1835 return source.SumNullable<int?, int?> (0, (a, b) => a.HasValue ? a + b : a);
1838 public static int Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int> selector)
1840 Check.SourceAndSelector (source, selector);
1842 return Sum<TSource, int> (source, (a, b) => a + selector (b));
1845 public static int? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, int?> selector)
1847 Check.SourceAndSelector (source, selector);
1849 return source.SumNullable<TSource, int?> (0, (a, b) => {
1850 var value = selector (b);
1851 return value.HasValue ? a + value.Value : a;
1855 public static long Sum (this IEnumerable<long> source)
1857 Check.Source (source);
1859 return Sum<long, long> (source, (a, b) => a + b);
1862 public static long? Sum (this IEnumerable<long?> source)
1864 Check.Source (source);
1866 return source.SumNullable<long?, long?> (0, (a, b) => a.HasValue ? a + b : a);
1869 public static long Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long> selector)
1871 Check.SourceAndSelector (source, selector);
1873 return Sum<TSource, long> (source, (a, b) => a + selector (b));
1876 public static long? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, long?> selector)
1878 Check.SourceAndSelector (source, selector);
1880 return source.SumNullable<TSource, long?> (0, (a, b) => {
1881 var value = selector (b);
1882 return value.HasValue ? a + value.Value : a;
1886 public static double Sum (this IEnumerable<double> source)
1888 Check.Source (source);
1890 return Sum<double, double> (source, (a, b) => a + b);
1893 public static double? Sum (this IEnumerable<double?> source)
1895 Check.Source (source);
1897 return source.SumNullable<double?, double?> (0, (a, b) => a.HasValue ? a + b : a);
1900 public static double Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double> selector)
1902 Check.SourceAndSelector (source, selector);
1904 return Sum<TSource, double> (source, (a, b) => a + selector (b));
1907 public static double? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, double?> selector)
1909 Check.SourceAndSelector (source, selector);
1911 return source.SumNullable<TSource, double?> (0, (a, b) => {
1912 var value = selector (b);
1913 return value.HasValue ? a + value.Value : a;
1917 public static float Sum (this IEnumerable<float> source)
1919 Check.Source (source);
1921 return Sum<float, float> (source, (a, b) => a + b);
1924 public static float? Sum (this IEnumerable<float?> source)
1926 Check.Source (source);
1928 return source.SumNullable<float?, float?> (0, (a, b) => a.HasValue ? a + b : a);
1931 public static float Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float> selector)
1933 Check.SourceAndSelector (source, selector);
1935 return Sum<TSource, float> (source, (a, b) => a + selector (b));
1938 public static float? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, float?> selector)
1940 Check.SourceAndSelector (source, selector);
1942 return source.SumNullable<TSource, float?> (0, (a, b) => {
1943 var value = selector (b);
1944 return value.HasValue ? a + value.Value : a;
1948 public static decimal Sum (this IEnumerable<decimal> source)
1950 Check.Source (source);
1952 return Sum<decimal, decimal> (source, (a, b) => a + b);
1955 public static decimal? Sum (this IEnumerable<decimal?> source)
1957 Check.Source (source);
1959 return source.SumNullable<decimal?, decimal?> (0, (a, b) => a.HasValue ? a + b : a);
1962 public static decimal Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal> selector)
1964 Check.SourceAndSelector (source, selector);
1966 return Sum<TSource, decimal> (source, (a, b) => a + selector (b));
1969 public static decimal? Sum<TSource> (this IEnumerable<TSource> source, Func<TSource, decimal?> selector)
1971 Check.SourceAndSelector (source, selector);
1973 return source.SumNullable<TSource, decimal?> (0, (a, b) => {
1974 var value = selector (b);
1975 return value.HasValue ? a + value.Value : a;
1979 static TR Sum<TA, TR> (this IEnumerable<TA> source, Func<TR, TA, TR> selector)
1981 TR total = default (TR);
1982 long counter = 0;
1983 foreach (var element in source) {
1984 total = selector (total, element);
1985 ++counter;
1988 return total;
1991 static TR SumNullable<TA, TR> (this IEnumerable<TA> source, TR zero, Func<TR, TA, TR> selector)
1993 TR total = zero;
1994 foreach (var element in source) {
1995 total = selector (total, element);
1998 return total;
2001 #endregion
2003 #region Take
2005 public static IEnumerable<TSource> Take<TSource> (this IEnumerable<TSource> source, int count)
2007 Check.Source (source);
2009 return CreateTakeIterator (source, count);
2012 static IEnumerable<TSource> CreateTakeIterator<TSource> (IEnumerable<TSource> source, int count)
2014 if (count <= 0)
2015 yield break;
2017 int counter = 0;
2018 foreach (TSource element in source) {
2019 yield return element;
2021 if (++counter == count)
2022 yield break;
2026 #endregion
2028 #region TakeWhile
2030 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2032 Check.SourceAndPredicate (source, predicate);
2034 return CreateTakeWhileIterator (source, predicate);
2037 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2039 foreach (var element in source) {
2040 if (!predicate (element))
2041 yield break;
2043 yield return element;
2047 public static IEnumerable<TSource> TakeWhile<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2049 Check.SourceAndPredicate (source, predicate);
2051 return CreateTakeWhileIterator (source, predicate);
2054 static IEnumerable<TSource> CreateTakeWhileIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2056 int counter = 0;
2057 foreach (var element in source) {
2058 if (!predicate (element, counter))
2059 yield break;
2061 yield return element;
2062 counter++;
2066 #endregion
2068 #region ThenBy
2070 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2072 return ThenBy<TSource, TKey> (source, keySelector, null);
2075 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2076 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2078 Check.SourceAndKeySelector (source, keySelector);
2080 return source.CreateOrderedEnumerable (keySelector, comparer, false);
2083 #endregion
2085 #region ThenByDescending
2087 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2088 Func<TSource, TKey> keySelector)
2090 return ThenByDescending<TSource, TKey> (source, keySelector, null);
2093 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
2094 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
2096 Check.SourceAndKeySelector (source, keySelector);
2098 return source.CreateOrderedEnumerable (keySelector, comparer, true);
2101 #endregion
2103 #region ToArray
2105 public static TSource [] ToArray<TSource> (this IEnumerable<TSource> source)
2107 Check.Source (source);
2109 var collection = source as ICollection<TSource>;
2110 if (collection != null) {
2111 var array = new TSource [collection.Count];
2112 collection.CopyTo (array, 0);
2113 return array;
2116 return new List<TSource> (source).ToArray ();
2119 #endregion
2121 #region ToDictionary
2122 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2123 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2125 return ToDictionary<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2128 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2129 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2131 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2133 if (comparer == null)
2134 comparer = EqualityComparer<TKey>.Default;
2136 var dict = new Dictionary<TKey, TElement> (comparer);
2137 foreach (var e in source)
2138 dict.Add (keySelector (e), elementSelector (e));
2140 return dict;
2143 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2144 Func<TSource, TKey> keySelector)
2146 return ToDictionary (source, keySelector, null);
2149 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey> (this IEnumerable<TSource> source,
2150 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2152 Check.SourceAndKeySelector (source, keySelector);
2154 if (comparer == null)
2155 comparer = EqualityComparer<TKey>.Default;
2157 var dict = new Dictionary<TKey, TSource> (comparer);
2158 foreach (var e in source)
2159 dict.Add (keySelector (e), e);
2161 return dict;
2164 #endregion
2166 #region ToList
2167 public static List<TSource> ToList<TSource> (this IEnumerable<TSource> source)
2169 Check.Source (source);
2171 return new List<TSource> (source);
2173 #endregion
2175 #region ToLookup
2177 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
2179 return ToLookup<TSource, TKey> (source, keySelector, null);
2182 public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
2183 Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
2185 Check.SourceAndKeySelector (source, keySelector);
2187 var dictionary = new Dictionary<TKey, List<TSource>> (comparer ?? EqualityComparer<TKey>.Default);
2188 foreach (TSource element in source) {
2189 TKey key = keySelector (element);
2190 if (key == null)
2191 throw new ArgumentNullException ();
2192 if (!dictionary.ContainsKey (key))
2193 dictionary.Add (key, new List<TSource> ());
2194 dictionary [key].Add (element);
2196 return new Lookup<TKey, TSource> (dictionary);
2199 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2200 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
2202 return ToLookup<TSource, TKey, TElement> (source, keySelector, elementSelector, null);
2205 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
2206 Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
2208 Check.SourceAndKeyElementSelectors (source, keySelector, elementSelector);
2210 Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>> (comparer ?? EqualityComparer<TKey>.Default);
2211 foreach (TSource element in source) {
2212 TKey key = keySelector (element);
2213 if (key == null)
2214 throw new ArgumentNullException ();
2215 if (!dictionary.ContainsKey (key))
2216 dictionary.Add (key, new List<TElement> ());
2217 dictionary [key].Add (elementSelector (element));
2219 return new Lookup<TKey, TElement> (dictionary);
2222 #endregion
2224 #region SequenceEqual
2226 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2228 return first.SequenceEqual (second, null);
2231 public static bool SequenceEqual<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2233 Check.FirstAndSecond (first, second);
2235 if (comparer == null)
2236 comparer = EqualityComparer<TSource>.Default;
2238 var first_enumerator = first.GetEnumerator ();
2239 var second_enumerator = second.GetEnumerator ();
2241 while (first_enumerator.MoveNext ()) {
2242 if (!second_enumerator.MoveNext ())
2243 return false;
2245 if (!comparer.Equals (first_enumerator.Current, second_enumerator.Current))
2246 return false;
2249 return !second_enumerator.MoveNext ();
2252 #endregion
2254 #region Union
2256 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second)
2258 Check.FirstAndSecond (first, second);
2260 return first.Union (second, null);
2263 public static IEnumerable<TSource> Union<TSource> (this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2265 Check.FirstAndSecond (first, second);
2267 if (comparer == null)
2268 comparer = EqualityComparer<TSource>.Default;
2270 return CreateUnionIterator (first, second, comparer);
2273 static IEnumerable<TSource> CreateUnionIterator<TSource> (IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
2275 var items = new HashSet<TSource> (comparer);
2276 foreach (var element in first) {
2277 if (! items.Contains (element)) {
2278 items.Add (element);
2279 yield return element;
2283 foreach (var element in second) {
2284 if (! items.Contains (element, comparer)) {
2285 items.Add (element);
2286 yield return element;
2291 #endregion
2293 #region Where
2295 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
2297 Check.SourceAndPredicate (source, predicate);
2299 return CreateWhereIterator (source, predicate);
2302 static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, bool> predicate)
2304 foreach (TSource element in source)
2305 if (predicate (element))
2306 yield return element;
2309 public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2311 Check.SourceAndPredicate (source, predicate);
2313 return CreateWhereIterator (source, predicate);
2316 static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
2318 int counter = 0;
2319 foreach (TSource element in source) {
2320 if (predicate (element, counter))
2321 yield return element;
2322 counter++;
2326 #endregion
2328 class ReadOnlyCollectionOf<T> {
2329 public static readonly ReadOnlyCollection<T> Empty = new ReadOnlyCollection<T> (new T [0]);
2332 internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
2334 if (source == null)
2335 return ReadOnlyCollectionOf<TSource>.Empty;
2337 var ro = source as ReadOnlyCollection<TSource>;
2338 if (ro != null)
2339 return ro;
2341 return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());