5 // Marek Safar (marek.safar@gmail.com)
6 // Antonello Provenzano <antonello@deveel.com>
7 // Alejandro Serrano "Serras" (trupill@yahoo.es)
8 // Jb Evain (jbevain@novell.com)
10 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 // precious: http://www.hookedonlinq.com
35 using System
.Collections
;
36 using System
.Collections
.Generic
;
37 using System
.Collections
.ObjectModel
;
41 public static class Enumerable
48 class PredicateOf
<T
> {
49 public static readonly Func
<T
, bool> Always
= (t
) => true;
54 public static TSource Aggregate
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, TSource
, TSource
> func
)
56 Check
.SourceAndFunc (source
, func
);
58 // custom foreach so that we can efficiently throw an exception
59 // if zero elements and treat the first element differently
60 using (var enumerator
= source
.GetEnumerator ()) {
61 if (!enumerator
.MoveNext ())
62 throw new InvalidOperationException ("No elements in source list");
64 TSource folded
= enumerator
.Current
;
65 while (enumerator
.MoveNext ())
66 folded
= func (folded
, enumerator
.Current
);
71 public static TAccumulate Aggregate
<TSource
, TAccumulate
> (this IEnumerable
<TSource
> source
,
72 TAccumulate seed
, Func
<TAccumulate
, TSource
, TAccumulate
> func
)
74 Check
.SourceAndFunc (source
, func
);
76 TAccumulate folded
= seed
;
77 foreach (TSource element
in source
)
78 folded
= func (folded
, element
);
83 public static TResult Aggregate
<TSource
, TAccumulate
, TResult
> (this IEnumerable
<TSource
> source
, TAccumulate seed
, Func
<TAccumulate
, TSource
, TAccumulate
> func
, Func
<TAccumulate
, TResult
> resultSelector
)
85 Check
.SourceAndFunc (source
, func
);
86 if (resultSelector
== null)
87 throw new ArgumentNullException ("resultSelector");
90 foreach (var e
in source
)
91 result
= func (result
, e
);
93 return resultSelector (result
);
100 public static bool All
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> predicate
)
102 Check
.SourceAndPredicate (source
, predicate
);
104 foreach (var element
in source
)
105 if (!predicate (element
))
115 public static bool Any
<TSource
> (this IEnumerable
<TSource
> source
)
117 Check
.Source (source
);
119 using (var enumerator
= source
.GetEnumerator ())
120 return enumerator
.MoveNext ();
123 public static bool Any
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> predicate
)
125 Check
.SourceAndPredicate (source
, predicate
);
127 foreach (TSource element
in source
)
128 if (predicate (element
))
138 public static IEnumerable
<TSource
> AsEnumerable
<TSource
> (this IEnumerable
<TSource
> source
)
147 public static double Average (this IEnumerable
<int> source
)
149 return Average
<int, long, double> (source
, (a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
152 public static double Average (this IEnumerable
<long> source
)
154 return Average
<long, long, double> (source
, (a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
157 public static double Average (this IEnumerable
<double> source
)
159 return Average
<double, double, double> (source
, (a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
162 public static float Average (this IEnumerable
<float> source
)
164 return Average
<float, double, float> (source
, (a
, b
) => a
+ b
, (a
, b
) => (float) a
/ (float) b
);
167 public static decimal Average (this IEnumerable
<decimal> source
)
169 return Average
<decimal, decimal, decimal> (source
, (a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
172 static TResult Average
<TElement
, TAggregate
, TResult
> (this IEnumerable
<TElement
> source
,
173 Func
<TAggregate
, TElement
, TAggregate
> func
, Func
<TAggregate
, long, TResult
> result
)
174 where TElement
: struct
175 where TAggregate
: struct
176 where TResult
: struct
178 Check
.Source (source
);
180 var total
= default (TAggregate
);
182 foreach (var element
in source
) {
183 total
= func (total
, element
);
188 throw new InvalidOperationException ();
190 return result (total
, counter
);
193 static TResult
? AverageNullable
<TElement
, TAggregate
, TResult
> (this IEnumerable
<TElement
?> source
,
194 Func
<TAggregate
, TElement
, TAggregate
> func
, Func
<TAggregate
, long, TResult
> result
)
195 where TElement
: struct
196 where TAggregate
: struct
197 where TResult
: struct
199 Check
.Source (source
);
201 var total
= default (TAggregate
);
203 foreach (var element
in source
) {
204 if (!element
.HasValue
)
207 total
= func (total
, element
.Value
);
214 return new TResult
? (result (total
, counter
));
217 public static double? Average (this IEnumerable
<int?> source
)
219 Check
.Source (source
);
221 return source
.AverageNullable
<int, long, double> ((a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
224 public static double? Average (this IEnumerable
<long?> source
)
226 Check
.Source (source
);
228 return source
.AverageNullable
<long, long, double> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
231 public static double? Average (this IEnumerable
<double?> source
)
233 Check
.Source (source
);
235 return source
.AverageNullable
<double, double, double> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
238 public static decimal? Average (this IEnumerable
<decimal?> source
)
240 Check
.Source (source
);
242 return source
.AverageNullable
<decimal, decimal, decimal> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
245 public static float? Average (this IEnumerable
<float?> source
)
247 Check
.Source (source
);
249 return source
.AverageNullable
<float, double, float> ((a
, b
) => a
+ b
, (a
, b
) => (float) a
/ (float) b
);
252 public static double Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, int> selector
)
254 Check
.SourceAndSelector (source
, selector
);
256 return source
.Select (selector
).Average
<int, long, double> ((a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
259 public static double? Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, int?> selector
)
261 Check
.SourceAndSelector (source
, selector
);
263 return source
.Select (selector
).AverageNullable
<int, long, double> ((a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
266 public static double Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, long> selector
)
268 Check
.SourceAndSelector (source
, selector
);
270 return source
.Select (selector
).Average
<long, long, double> ((a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
273 public static double? Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, long?> selector
)
275 Check
.SourceAndSelector (source
, selector
);
277 return source
.Select (selector
).AverageNullable
<long, long, double> ((a
, b
) => a
+ b
, (a
, b
) => (double) a
/ (double) b
);
280 public static double Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, double> selector
)
282 Check
.SourceAndSelector (source
, selector
);
284 return source
.Select (selector
).Average
<double, double, double> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
287 public static double? Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, double?> selector
)
289 Check
.SourceAndSelector (source
, selector
);
291 return source
.Select (selector
).AverageNullable
<double, double, double> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
294 public static float Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, float> selector
)
296 Check
.SourceAndSelector (source
, selector
);
298 return source
.Select (selector
).Average
<float, double, float> ((a
, b
) => a
+ b
, (a
, b
) => (float) a
/ (float) b
);
301 public static float? Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, float?> selector
)
303 Check
.SourceAndSelector (source
, selector
);
305 return source
.Select (selector
).AverageNullable
<float, double, float> ((a
, b
) => a
+ b
, (a
, b
) => (float) a
/ (float) b
);
308 public static decimal Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, decimal> selector
)
310 Check
.SourceAndSelector (source
, selector
);
312 return source
.Select (selector
).Average
<decimal, decimal, decimal> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
315 public static decimal? Average
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, decimal?> selector
)
317 Check
.SourceAndSelector (source
, selector
);
319 return source
.Select (selector
).AverageNullable
<decimal, decimal, decimal> ((a
, b
) => a
+ b
, (a
, b
) => a
/ b
);
326 public static IEnumerable
<TResult
> Cast
<TResult
> (this IEnumerable source
)
328 Check
.Source (source
);
330 return CreateCastIterator
<TResult
> (source
);
333 static IEnumerable
<TResult
> CreateCastIterator
<TResult
> (IEnumerable source
)
335 foreach (object element
in source
)
336 yield return (TResult
) element
;
343 public static IEnumerable
<TSource
> Concat
<TSource
> (this IEnumerable
<TSource
> first
, IEnumerable
<TSource
> second
)
345 Check
.FirstAndSecond (first
, second
);
347 return CreateConcatIterator (first
, second
);
350 static IEnumerable
<TSource
> CreateConcatIterator
<TSource
> (IEnumerable
<TSource
> first
, IEnumerable
<TSource
> second
)
352 foreach (TSource element
in first
)
353 yield return element
;
354 foreach (TSource element
in second
)
355 yield return element
;
362 public static bool Contains
<TSource
> (this IEnumerable
<TSource
> source
, TSource
value)
364 var collection
= source
as ICollection
<TSource
>;
365 if (collection
!= null)
366 return collection
.Contains (value);
368 return Contains
<TSource
> (source
, value, null);
371 public static bool Contains
<TSource
> (this IEnumerable
<TSource
> source
, TSource
value, IEqualityComparer
<TSource
> comparer
)
373 Check
.Source (source
);
375 if (comparer
== null)
376 comparer
= EqualityComparer
<TSource
>.Default
;
378 foreach (var element
in source
)
379 if (comparer
.Equals (element
, value))
388 public static int Count
<TSource
> (this IEnumerable
<TSource
> source
)
390 Check
.Source (source
);
392 var collection
= source
as ICollection
<TSource
>;
393 if (collection
!= null)
394 return collection
.Count
;
397 using (var enumerator
= source
.GetEnumerator ())
398 while (enumerator
.MoveNext ())
404 public static int Count
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> selector
)
406 Check
.SourceAndSelector (source
, selector
);
409 foreach (var element
in source
)
410 if (selector (element
))
418 #region DefaultIfEmpty
420 public static IEnumerable
<TSource
> DefaultIfEmpty
<TSource
> (this IEnumerable
<TSource
> source
)
422 return DefaultIfEmpty (source
, default (TSource
));
425 public static IEnumerable
<TSource
> DefaultIfEmpty
<TSource
> (this IEnumerable
<TSource
> source
, TSource defaultValue
)
427 Check
.Source (source
);
429 return CreateDefaultIfEmptyIterator (source
, defaultValue
);
432 static IEnumerable
<TSource
> CreateDefaultIfEmptyIterator
<TSource
> (IEnumerable
<TSource
> source
, TSource defaultValue
)
435 foreach (TSource item
in source
) {
441 yield return defaultValue
;
448 public static IEnumerable
<TSource
> Distinct
<TSource
> (this IEnumerable
<TSource
> source
)
450 return Distinct
<TSource
> (source
, null);
453 public static IEnumerable
<TSource
> Distinct
<TSource
> (this IEnumerable
<TSource
> source
, IEqualityComparer
<TSource
> comparer
)
455 Check
.Source (source
);
457 if (comparer
== null)
458 comparer
= EqualityComparer
<TSource
>.Default
;
460 return CreateDistinctIterator (source
, comparer
);
463 static IEnumerable
<TSource
> CreateDistinctIterator
<TSource
> (IEnumerable
<TSource
> source
, IEqualityComparer
<TSource
> comparer
)
465 var items
= new HashSet
<TSource
> (comparer
);
466 foreach (var element
in source
) {
467 if (! items
.Contains (element
)) {
469 yield return element
;
478 static TSource ElementAt
<TSource
> (this IEnumerable
<TSource
> source
, int index
, Fallback fallback
)
482 foreach (var element
in source
) {
483 if (index
== counter
++)
487 if (fallback
== Fallback
.Throw
)
488 throw new ArgumentOutOfRangeException ();
490 return default (TSource
);
493 public static TSource ElementAt
<TSource
> (this IEnumerable
<TSource
> source
, int index
)
495 Check
.Source (source
);
498 throw new ArgumentOutOfRangeException ();
500 var list
= source
as IList
<TSource
>;
504 return source
.ElementAt (index
, Fallback
.Throw
);
509 #region ElementAtOrDefault
511 public static TSource ElementAtOrDefault
<TSource
> (this IEnumerable
<TSource
> source
, int index
)
513 Check
.Source (source
);
516 return default (TSource
);
518 var list
= source
as IList
<TSource
>;
520 return index
< list
.Count
? list
[index
] : default (TSource
);
522 return source
.ElementAt (index
, Fallback
.Default
);
529 public static IEnumerable
<TResult
> Empty
<TResult
> ()
531 return new TResult
[0];
538 public static IEnumerable
<TSource
> Except
<TSource
> (this IEnumerable
<TSource
> first
, IEnumerable
<TSource
> second
)
540 return Except (first
, second
, null);
543 public static IEnumerable
<TSource
> Except
<TSource
> (this IEnumerable
<TSource
> first
, IEnumerable
<TSource
> second
, IEqualityComparer
<TSource
> comparer
)
545 Check
.FirstAndSecond (first
, second
);
547 if (comparer
== null)
548 comparer
= EqualityComparer
<TSource
>.Default
;
550 return CreateExceptIterator (first
, second
, comparer
);
553 static IEnumerable
<TSource
> CreateExceptIterator
<TSource
> (IEnumerable
<TSource
> first
, IEnumerable
<TSource
> second
, IEqualityComparer
<TSource
> comparer
)
555 var items
= new HashSet
<TSource
> (second
, comparer
);
556 foreach (var element
in first
) {
557 if (!items
.Contains (element
, comparer
))
558 yield return element
;
566 static TSource First
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> predicate
, Fallback fallback
)
568 foreach (var element
in source
)
569 if (predicate (element
))
572 if (fallback
== Fallback
.Throw
)
573 throw new InvalidOperationException ();
575 return default (TSource
);
578 public static TSource First
<TSource
> (this IEnumerable
<TSource
> source
)
580 Check
.Source (source
);
582 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
);
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
);
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
))
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
> ();
645 int nullCounter
= -1;
647 foreach (TSource element
in source
) {
648 TKey key
= keySelector (element
);
650 nullList
.Add (element
);
651 if (nullCounter
== -1) {
652 nullCounter
= counter
;
656 List
<TSource
> group = ContainsGroup
<TKey
, TSource
> (groups
, key
, comparer
);
658 group = new List
<TSource
> ();
659 groups
.Add (key
, group);
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
;
673 Grouping
<TKey
, TSource
> grouping
= new Grouping
<TKey
, TSource
> (group.Key
, group.Value
);
674 yield return grouping
;
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
> ();
693 int nullCounter
= -1;
695 foreach (TSource item
in source
) {
696 TKey key
= keySelector (item
);
697 TElement element
= elementSelector (item
);
699 nullList
.Add (element
);
700 if (nullCounter
== -1) {
701 nullCounter
= counter
;
705 List
<TElement
> group = ContainsGroup
<TKey
, TElement
> (groups
, key
, comparer
);
707 group = new List
<TElement
> ();
708 groups
.Add (key
, group);
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
;
722 Grouping
<TKey
, TElement
> grouping
= new Grouping
<TKey
, TElement
> (group.Key
, group.Value
);
723 yield return grouping
;
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);
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
]);
809 yield return resultSelector (element
, Empty
<TInner
> ());
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
;
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);
891 static TSource Last
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> predicate
, Fallback fallback
)
894 var item
= default (TSource
);
896 foreach (var element
in source
) {
897 if (!predicate (element
))
907 if (fallback
== Fallback
.Throw
)
908 throw new InvalidOperationException ();
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
);
929 #region LastOrDefault
931 public static TSource LastOrDefault
<TSource
> (this IEnumerable
<TSource
> source
)
933 Check
.Source (source
);
935 var list
= source
as IList
<TSource
>;
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
);
953 public static long LongCount
<TSource
> (this IEnumerable
<TSource
> source
)
955 Check
.Source (source
);
958 var array
= source
as TSource
[];
960 return array
.LongLength
;
964 using (var enumerator
= source
.GetEnumerator ())
965 while (enumerator
.MoveNext ())
971 public static long LongCount
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> selector
)
973 Check
.SourceAndSelector (source
, selector
);
976 foreach (TSource element
in source
)
977 if (selector (element
))
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
1060 T
? value = initValue
;
1061 foreach (var element
in source
) {
1062 if (!element
.HasValue
)
1065 if (selector (element
.Value
, value))
1076 public static TSource Max
<TSource
> (this IEnumerable
<TSource
> source
)
1078 Check
.Source (source
);
1080 bool notAssigned
= true;
1081 TSource maximum
= default (TSource
);
1083 foreach (TSource element
in source
) {
1086 notAssigned
= false;
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
);
1094 throw new ArgumentNullException ();
1103 throw new InvalidOperationException ();
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
)
1146 foreach (var element
in source
) {
1147 initValue
= selector (element
, initValue
);
1152 throw new InvalidOperationException ();
1157 static U
? IterateNullable
<T
, U
> (IEnumerable
<T
> source
, U initialValue
, Func
<T
, U
?, U
?> selector
) where U
: struct
1160 U
? value = initialValue
;
1161 foreach (var element
in source
) {
1162 value = selector (element
, value);
1163 if (!value.HasValue
)
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
);
1227 foreach (TSource item
in source
) {
1228 TResult element
= selector (item
);
1231 notAssigned
= false;
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
);
1239 throw new ArgumentNullException ();
1248 throw new InvalidOperationException ();
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
);
1334 foreach (TSource element
in source
) {
1337 notAssigned
= false;
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
);
1345 throw new ArgumentNullException ();
1354 throw new InvalidOperationException ();
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
);
1446 foreach (TSource item
in source
) {
1447 TResult element
= selector (item
);
1450 notAssigned
= false;
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
);
1458 throw new ArgumentNullException ();
1467 throw new InvalidOperationException ();
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
;
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
);
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
);
1531 public static IEnumerable
<int> Range (int start
, int count
)
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
++)
1554 public static IEnumerable
<TResult
> Repeat
<TResult
> (TResult element
, int count
)
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
;
1572 public static IEnumerable
<TSource
> Reverse
<TSource
> (this IEnumerable
<TSource
> source
)
1574 Check
.Source (source
);
1576 var list
= source
as IList
<TSource
>;
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];
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
)
1616 foreach (TSource element
in source
) {
1617 yield return selector (element
, counter
);
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
))
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
)
1650 foreach (TSource element
in source
) {
1651 foreach (TResult item
in selector (element
, 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
)
1685 foreach (TSource element
in source
)
1686 foreach (TCollection collection
in collectionSelector (element
, counter
++))
1687 yield return selector (element
, collection
);
1694 static TSource Single
<TSource
> (this IEnumerable
<TSource
> source
, Func
<TSource
, bool> predicate
, Fallback fallback
)
1697 var item
= default (TSource
);
1699 foreach (var element
in source
) {
1700 if (!predicate (element
))
1704 throw new InvalidOperationException ();
1710 if (!found
&& fallback
== Fallback
.Throw
)
1711 throw new InvalidOperationException ();
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
);
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
);
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
)
1762 foreach (var element
in source
) {
1766 yield return element
;
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
)
1785 foreach (TSource element
in source
) {
1787 yield return element
;
1789 if (!predicate (element
)) {
1790 yield return element
;
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
)
1808 foreach (TSource element
in source
) {
1810 yield return element
;
1812 if (!predicate (element
, counter
)) {
1813 yield return element
;
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
);
1983 foreach (var element
in source
) {
1984 total
= selector (total
, element
);
1991 static TR SumNullable
<TA
, TR
> (this IEnumerable
<TA
> source
, TR zero
, Func
<TR
, TA
, TR
> selector
)
1994 foreach (var element
in source
) {
1995 total
= selector (total
, element
);
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
)
2018 foreach (TSource element
in source
) {
2019 yield return element
;
2021 if (++counter
== count
)
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
))
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
)
2057 foreach (var element
in source
) {
2058 if (!predicate (element
, counter
))
2061 yield return element
;
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);
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);
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);
2116 return new List
<TSource
> (source
).ToArray ();
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
));
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
);
2167 public static List
<TSource
> ToList
<TSource
> (this IEnumerable
<TSource
> source
)
2169 Check
.Source (source
);
2171 return new List
<TSource
> (source
);
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
);
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
);
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
);
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 ())
2245 if (!comparer
.Equals (first_enumerator
.Current
, second_enumerator
.Current
))
2249 return !second_enumerator
.MoveNext ();
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
;
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
)
2319 foreach (TSource element
in source
) {
2320 if (predicate (element
, counter
))
2321 yield return element
;
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
)
2335 return ReadOnlyCollectionOf
<TSource
>.Empty
;
2337 var ro
= source
as ReadOnlyCollection
<TSource
>;
2341 return new ReadOnlyCollection
<TSource
> (source
.ToArray
<TSource
> ());