1 #if NET20 2 3 #region License, Terms and Author(s) 4 // 5 // LINQBridge 6 // Copyright (c) 2007-9 Atif Aziz, Joseph Albahari. All rights reserved. 7 // 8 // Author(s): 9 // 10 // Atif Aziz, http://www.raboof.com 11 // 12 // This library is free software; you can redistribute it and/or modify it 13 // under the terms of the New BSD License, a copy of which should have 14 // been delivered along with this distribution. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 // 28 #endregion 29 30 using System; 31 using System.Collections; 32 using System.Collections.Generic; 33 using System.Diagnostics; 34 using Newtonsoft.Json.Serialization; 35 36 namespace Newtonsoft.Json.Utilities.LinqBridge 37 { 38 /// <summary> 39 /// Provides a set of static (Shared in Visual Basic) methods for 40 /// querying objects that implement <see cref="IEnumerable{T}" />. 41 /// </summary> 42 internal static partial class Enumerable 43 { 44 /// <summary> 45 /// Returns the input typed as <see cref="IEnumerable{T}"/>. 46 /// </summary> 47 AsEnumerable(IEnumerable<TSource> source)48 public static IEnumerable<TSource> AsEnumerable<TSource>(IEnumerable<TSource> source) 49 { 50 return source; 51 } 52 53 /// <summary> 54 /// Returns an empty <see cref="IEnumerable{T}"/> that has the 55 /// specified type argument. 56 /// </summary> 57 Empty()58 public static IEnumerable<TResult> Empty<TResult>() 59 { 60 return Sequence<TResult>.Empty; 61 } 62 63 /// <summary> 64 /// Converts the elements of an <see cref="IEnumerable"/> to the 65 /// specified type. 66 /// </summary> 67 Cast( this IEnumerable source)68 public static IEnumerable<TResult> Cast<TResult>( 69 this IEnumerable source) 70 { 71 CheckNotNull(source, "source"); 72 73 return CastYield<TResult>(source); 74 } 75 CastYield( IEnumerable source)76 private static IEnumerable<TResult> CastYield<TResult>( 77 IEnumerable source) 78 { 79 foreach (var item in source) 80 yield return (TResult) item; 81 } 82 83 /// <summary> 84 /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type. 85 /// </summary> 86 OfType( this IEnumerable source)87 public static IEnumerable<TResult> OfType<TResult>( 88 this IEnumerable source) 89 { 90 CheckNotNull(source, "source"); 91 92 return OfTypeYield<TResult>(source); 93 } 94 OfTypeYield( IEnumerable source)95 private static IEnumerable<TResult> OfTypeYield<TResult>( 96 IEnumerable source) 97 { 98 foreach (var item in source) 99 if (item is TResult) 100 yield return (TResult) item; 101 } 102 103 /// <summary> 104 /// Generates a sequence of integral numbers within a specified range. 105 /// </summary> 106 /// <param name="start">The value of the first integer in the sequence.</param> 107 /// <param name="count">The number of sequential integers to generate.</param> 108 Range(int start, int count)109 public static IEnumerable<int> Range(int start, int count) 110 { 111 if (count < 0) 112 throw new ArgumentOutOfRangeException("count", count, null); 113 114 var end = (long) start + count; 115 if (end - 1 >= int.MaxValue) 116 throw new ArgumentOutOfRangeException("count", count, null); 117 118 return RangeYield(start, end); 119 } 120 RangeYield(int start, long end)121 private static IEnumerable<int> RangeYield(int start, long end) 122 { 123 for (var i = start; i < end; i++) 124 yield return i; 125 } 126 127 /// <summary> 128 /// Generates a sequence that contains one repeated value. 129 /// </summary> 130 Repeat(TResult element, int count)131 public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count) 132 { 133 if (count < 0) throw new ArgumentOutOfRangeException("count", count, null); 134 135 return RepeatYield(element, count); 136 } 137 RepeatYield(TResult element, int count)138 private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count) 139 { 140 for (var i = 0; i < count; i++) 141 yield return element; 142 } 143 144 /// <summary> 145 /// Filters a sequence of values based on a predicate. 146 /// </summary> 147 Where( this IEnumerable<TSource> source, Func<TSource, bool> predicate)148 public static IEnumerable<TSource> Where<TSource>( 149 this IEnumerable<TSource> source, 150 Func<TSource, bool> predicate) 151 { 152 CheckNotNull(predicate, "predicate"); 153 154 return source.Where((item, i) => predicate(item)); 155 } 156 157 /// <summary> 158 /// Filters a sequence of values based on a predicate. 159 /// Each element's index is used in the logic of the predicate function. 160 /// </summary> 161 Where( this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)162 public static IEnumerable<TSource> Where<TSource>( 163 this IEnumerable<TSource> source, 164 Func<TSource, int, bool> predicate) 165 { 166 CheckNotNull(source, "source"); 167 CheckNotNull(predicate, "predicate"); 168 169 return WhereYield(source, predicate); 170 } 171 WhereYield( IEnumerable<TSource> source, Func<TSource, int, bool> predicate)172 private static IEnumerable<TSource> WhereYield<TSource>( 173 IEnumerable<TSource> source, 174 Func<TSource, int, bool> predicate) 175 { 176 var i = 0; 177 foreach (var item in source) 178 if (predicate(item, i++)) 179 yield return item; 180 } 181 182 /// <summary> 183 /// Projects each element of a sequence into a new form. 184 /// </summary> 185 Select( this IEnumerable<TSource> source, Func<TSource, TResult> selector)186 public static IEnumerable<TResult> Select<TSource, TResult>( 187 this IEnumerable<TSource> source, 188 Func<TSource, TResult> selector) 189 { 190 CheckNotNull(selector, "selector"); 191 192 return source.Select((item, i) => selector(item)); 193 } 194 195 /// <summary> 196 /// Projects each element of a sequence into a new form by 197 /// incorporating the element's index. 198 /// </summary> 199 Select( this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)200 public static IEnumerable<TResult> Select<TSource, TResult>( 201 this IEnumerable<TSource> source, 202 Func<TSource, int, TResult> selector) 203 { 204 CheckNotNull(source, "source"); 205 CheckNotNull(selector, "selector"); 206 207 return SelectYield(source, selector); 208 } 209 SelectYield( IEnumerable<TSource> source, Func<TSource, int, TResult> selector)210 private static IEnumerable<TResult> SelectYield<TSource, TResult>( 211 IEnumerable<TSource> source, 212 Func<TSource, int, TResult> selector) 213 { 214 var i = 0; 215 foreach (var item in source) 216 yield return selector(item, i++); 217 } 218 219 /// <summary> 220 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" /> 221 /// and flattens the resulting sequences into one sequence. 222 /// </summary> 223 SelectMany( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)224 public static IEnumerable<TResult> SelectMany<TSource, TResult>( 225 this IEnumerable<TSource> source, 226 Func<TSource, IEnumerable<TResult>> selector) 227 { 228 CheckNotNull(selector, "selector"); 229 230 return source.SelectMany((item, i) => selector(item)); 231 } 232 233 /// <summary> 234 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 235 /// and flattens the resulting sequences into one sequence. The 236 /// index of each source element is used in the projected form of 237 /// that element. 238 /// </summary> 239 SelectMany( this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)240 public static IEnumerable<TResult> SelectMany<TSource, TResult>( 241 this IEnumerable<TSource> source, 242 Func<TSource, int, IEnumerable<TResult>> selector) 243 { 244 CheckNotNull(selector, "selector"); 245 246 return source.SelectMany(selector, (item, subitem) => subitem); 247 } 248 249 /// <summary> 250 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 251 /// flattens the resulting sequences into one sequence, and invokes 252 /// a result selector function on each element therein. 253 /// </summary> 254 SelectMany( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)255 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>( 256 this IEnumerable<TSource> source, 257 Func<TSource, IEnumerable<TCollection>> collectionSelector, 258 Func<TSource, TCollection, TResult> resultSelector) 259 { 260 CheckNotNull(collectionSelector, "collectionSelector"); 261 262 return source.SelectMany((item, i) => collectionSelector(item), resultSelector); 263 } 264 265 /// <summary> 266 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />, 267 /// flattens the resulting sequences into one sequence, and invokes 268 /// a result selector function on each element therein. The index of 269 /// each source element is used in the intermediate projected form 270 /// of that element. 271 /// </summary> 272 SelectMany( this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)273 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>( 274 this IEnumerable<TSource> source, 275 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, 276 Func<TSource, TCollection, TResult> resultSelector) 277 { 278 CheckNotNull(source, "source"); 279 CheckNotNull(collectionSelector, "collectionSelector"); 280 CheckNotNull(resultSelector, "resultSelector"); 281 282 return SelectManyYield(source, collectionSelector, resultSelector); 283 } 284 SelectManyYield( this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)285 private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>( 286 this IEnumerable<TSource> source, 287 Func<TSource, int, IEnumerable<TCollection>> collectionSelector, 288 Func<TSource, TCollection, TResult> resultSelector) 289 { 290 var i = 0; 291 foreach (var item in source) 292 foreach (var subitem in collectionSelector(item, i++)) 293 yield return resultSelector(item, subitem); 294 } 295 296 /// <summary> 297 /// Returns elements from a sequence as long as a specified condition is true. 298 /// </summary> 299 TakeWhile( this IEnumerable<TSource> source, Func<TSource, bool> predicate)300 public static IEnumerable<TSource> TakeWhile<TSource>( 301 this IEnumerable<TSource> source, 302 Func<TSource, bool> predicate) 303 { 304 CheckNotNull(predicate, "predicate"); 305 306 return source.TakeWhile((item, i) => predicate(item)); 307 } 308 309 /// <summary> 310 /// Returns elements from a sequence as long as a specified condition is true. 311 /// The element's index is used in the logic of the predicate function. 312 /// </summary> 313 TakeWhile( this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)314 public static IEnumerable<TSource> TakeWhile<TSource>( 315 this IEnumerable<TSource> source, 316 Func<TSource, int, bool> predicate) 317 { 318 CheckNotNull(source, "source"); 319 CheckNotNull(predicate, "predicate"); 320 321 return TakeWhileYield(source, predicate); 322 } 323 TakeWhileYield( this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)324 private static IEnumerable<TSource> TakeWhileYield<TSource>( 325 this IEnumerable<TSource> source, 326 Func<TSource, int, bool> predicate) 327 { 328 var i = 0; 329 foreach (var item in source) 330 if (predicate(item, i++)) 331 yield return item; 332 else 333 break; 334 } 335 336 private static class Futures<T> 337 { 338 public static readonly Func<T> Default = () => default(T); 339 public static readonly Func<T> Undefined = () => { throw new InvalidOperationException(); }; 340 } 341 342 /// <summary> 343 /// Base implementation of First operator. 344 /// </summary> 345 FirstImpl( this IEnumerable<TSource> source, Func<TSource> empty)346 private static TSource FirstImpl<TSource>( 347 this IEnumerable<TSource> source, 348 Func<TSource> empty) 349 { 350 CheckNotNull(source, "source"); 351 Debug.Assert(empty != null); 352 353 var list = source as IList<TSource>; // optimized case for lists 354 if (list != null) 355 return list.Count > 0 ? list[0] : empty(); 356 357 using (var e = source.GetEnumerator()) // fallback for enumeration 358 return e.MoveNext() ? e.Current : empty(); 359 } 360 361 /// <summary> 362 /// Returns the first element of a sequence. 363 /// </summary> 364 First( this IEnumerable<TSource> source)365 public static TSource First<TSource>( 366 this IEnumerable<TSource> source) 367 { 368 return source.FirstImpl(Futures<TSource>.Undefined); 369 } 370 371 /// <summary> 372 /// Returns the first element in a sequence that satisfies a specified condition. 373 /// </summary> 374 First( this IEnumerable<TSource> source, Func<TSource, bool> predicate)375 public static TSource First<TSource>( 376 this IEnumerable<TSource> source, 377 Func<TSource, bool> predicate) 378 { 379 return First(source.Where(predicate)); 380 } 381 382 /// <summary> 383 /// Returns the first element of a sequence, or a default value if 384 /// the sequence contains no elements. 385 /// </summary> 386 FirstOrDefault( this IEnumerable<TSource> source)387 public static TSource FirstOrDefault<TSource>( 388 this IEnumerable<TSource> source) 389 { 390 return source.FirstImpl(Futures<TSource>.Default); 391 } 392 393 /// <summary> 394 /// Returns the first element of the sequence that satisfies a 395 /// condition or a default value if no such element is found. 396 /// </summary> 397 FirstOrDefault( this IEnumerable<TSource> source, Func<TSource, bool> predicate)398 public static TSource FirstOrDefault<TSource>( 399 this IEnumerable<TSource> source, 400 Func<TSource, bool> predicate) 401 { 402 return FirstOrDefault(source.Where(predicate)); 403 } 404 405 /// <summary> 406 /// Base implementation of Last operator. 407 /// </summary> 408 LastImpl( this IEnumerable<TSource> source, Func<TSource> empty)409 private static TSource LastImpl<TSource>( 410 this IEnumerable<TSource> source, 411 Func<TSource> empty) 412 { 413 CheckNotNull(source, "source"); 414 415 var list = source as IList<TSource>; // optimized case for lists 416 if (list != null) 417 return list.Count > 0 ? list[list.Count - 1] : empty(); 418 419 using (var e = source.GetEnumerator()) 420 { 421 if (!e.MoveNext()) 422 return empty(); 423 424 var last = e.Current; 425 while (e.MoveNext()) 426 last = e.Current; 427 428 return last; 429 } 430 } 431 432 /// <summary> 433 /// Returns the last element of a sequence. 434 /// </summary> Last( this IEnumerable<TSource> source)435 public static TSource Last<TSource>( 436 this IEnumerable<TSource> source) 437 { 438 return source.LastImpl(Futures<TSource>.Undefined); 439 } 440 441 /// <summary> 442 /// Returns the last element of a sequence that satisfies a 443 /// specified condition. 444 /// </summary> 445 Last( this IEnumerable<TSource> source, Func<TSource, bool> predicate)446 public static TSource Last<TSource>( 447 this IEnumerable<TSource> source, 448 Func<TSource, bool> predicate) 449 { 450 return Last(source.Where(predicate)); 451 } 452 453 /// <summary> 454 /// Returns the last element of a sequence, or a default value if 455 /// the sequence contains no elements. 456 /// </summary> 457 LastOrDefault( this IEnumerable<TSource> source)458 public static TSource LastOrDefault<TSource>( 459 this IEnumerable<TSource> source) 460 { 461 return source.LastImpl(Futures<TSource>.Default); 462 } 463 464 /// <summary> 465 /// Returns the last element of a sequence that satisfies a 466 /// condition or a default value if no such element is found. 467 /// </summary> 468 LastOrDefault( this IEnumerable<TSource> source, Func<TSource, bool> predicate)469 public static TSource LastOrDefault<TSource>( 470 this IEnumerable<TSource> source, 471 Func<TSource, bool> predicate) 472 { 473 return LastOrDefault(source.Where(predicate)); 474 } 475 476 /// <summary> 477 /// Base implementation of Single operator. 478 /// </summary> 479 SingleImpl( this IEnumerable<TSource> source, Func<TSource> empty)480 private static TSource SingleImpl<TSource>( 481 this IEnumerable<TSource> source, 482 Func<TSource> empty) 483 { 484 CheckNotNull(source, "source"); 485 486 using (var e = source.GetEnumerator()) 487 { 488 if (e.MoveNext()) 489 { 490 var single = e.Current; 491 if (!e.MoveNext()) 492 return single; 493 494 throw new InvalidOperationException(); 495 } 496 497 return empty(); 498 } 499 } 500 501 /// <summary> 502 /// Returns the only element of a sequence, and throws an exception 503 /// if there is not exactly one element in the sequence. 504 /// </summary> 505 Single( this IEnumerable<TSource> source)506 public static TSource Single<TSource>( 507 this IEnumerable<TSource> source) 508 { 509 return source.SingleImpl(Futures<TSource>.Undefined); 510 } 511 512 /// <summary> 513 /// Returns the only element of a sequence that satisfies a 514 /// specified condition, and throws an exception if more than one 515 /// such element exists. 516 /// </summary> 517 Single( this IEnumerable<TSource> source, Func<TSource, bool> predicate)518 public static TSource Single<TSource>( 519 this IEnumerable<TSource> source, 520 Func<TSource, bool> predicate) 521 { 522 return Single(source.Where(predicate)); 523 } 524 525 /// <summary> 526 /// Returns the only element of a sequence, or a default value if 527 /// the sequence is empty; this method throws an exception if there 528 /// is more than one element in the sequence. 529 /// </summary> 530 SingleOrDefault( this IEnumerable<TSource> source)531 public static TSource SingleOrDefault<TSource>( 532 this IEnumerable<TSource> source) 533 { 534 return source.SingleImpl(Futures<TSource>.Default); 535 } 536 537 /// <summary> 538 /// Returns the only element of a sequence that satisfies a 539 /// specified condition or a default value if no such element 540 /// exists; this method throws an exception if more than one element 541 /// satisfies the condition. 542 /// </summary> 543 SingleOrDefault( this IEnumerable<TSource> source, Func<TSource, bool> predicate)544 public static TSource SingleOrDefault<TSource>( 545 this IEnumerable<TSource> source, 546 Func<TSource, bool> predicate) 547 { 548 return SingleOrDefault(source.Where(predicate)); 549 } 550 551 /// <summary> 552 /// Returns the element at a specified index in a sequence. 553 /// </summary> 554 ElementAt( this IEnumerable<TSource> source, int index)555 public static TSource ElementAt<TSource>( 556 this IEnumerable<TSource> source, 557 int index) 558 { 559 CheckNotNull(source, "source"); 560 561 if (index < 0) 562 throw new ArgumentOutOfRangeException("index", index, null); 563 564 var list = source as IList<TSource>; 565 if (list != null) 566 return list[index]; 567 568 try 569 { 570 return source.SkipWhile((item, i) => i < index).First(); 571 } 572 catch (InvalidOperationException) // if thrown by First 573 { 574 throw new ArgumentOutOfRangeException("index", index, null); 575 } 576 } 577 578 /// <summary> 579 /// Returns the element at a specified index in a sequence or a 580 /// default value if the index is out of range. 581 /// </summary> 582 ElementAtOrDefault( this IEnumerable<TSource> source, int index)583 public static TSource ElementAtOrDefault<TSource>( 584 this IEnumerable<TSource> source, 585 int index) 586 { 587 CheckNotNull(source, "source"); 588 589 if (index < 0) 590 return default(TSource); 591 592 var list = source as IList<TSource>; 593 if (list != null) 594 return index < list.Count ? list[index] : default(TSource); 595 596 return source.SkipWhile((item, i) => i < index).FirstOrDefault(); 597 } 598 599 /// <summary> 600 /// Inverts the order of the elements in a sequence. 601 /// </summary> 602 Reverse( this IEnumerable<TSource> source)603 public static IEnumerable<TSource> Reverse<TSource>( 604 this IEnumerable<TSource> source) 605 { 606 CheckNotNull(source, "source"); 607 608 return ReverseYield(source); 609 } 610 ReverseYield(IEnumerable<TSource> source)611 private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source) 612 { 613 var stack = new Stack<TSource>(); 614 foreach (var item in source) 615 stack.Push(item); 616 617 foreach (var item in stack) 618 yield return item; 619 } 620 621 /// <summary> 622 /// Returns a specified number of contiguous elements from the start 623 /// of a sequence. 624 /// </summary> 625 Take( this IEnumerable<TSource> source, int count)626 public static IEnumerable<TSource> Take<TSource>( 627 this IEnumerable<TSource> source, 628 int count) 629 { 630 return source.Where((item, i) => i < count); 631 } 632 633 /// <summary> 634 /// Bypasses a specified number of elements in a sequence and then 635 /// returns the remaining elements. 636 /// </summary> 637 Skip( this IEnumerable<TSource> source, int count)638 public static IEnumerable<TSource> Skip<TSource>( 639 this IEnumerable<TSource> source, 640 int count) 641 { 642 return source.Where((item, i) => i >= count); 643 } 644 645 /// <summary> 646 /// Bypasses elements in a sequence as long as a specified condition 647 /// is true and then returns the remaining elements. 648 /// </summary> 649 SkipWhile( this IEnumerable<TSource> source, Func<TSource, bool> predicate)650 public static IEnumerable<TSource> SkipWhile<TSource>( 651 this IEnumerable<TSource> source, 652 Func<TSource, bool> predicate) 653 { 654 CheckNotNull(predicate, "predicate"); 655 656 return source.SkipWhile((item, i) => predicate(item)); 657 } 658 659 /// <summary> 660 /// Bypasses elements in a sequence as long as a specified condition 661 /// is true and then returns the remaining elements. The element's 662 /// index is used in the logic of the predicate function. 663 /// </summary> 664 SkipWhile( this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)665 public static IEnumerable<TSource> SkipWhile<TSource>( 666 this IEnumerable<TSource> source, 667 Func<TSource, int, bool> predicate) 668 { 669 CheckNotNull(source, "source"); 670 CheckNotNull(predicate, "predicate"); 671 672 return SkipWhileYield(source, predicate); 673 } 674 SkipWhileYield( IEnumerable<TSource> source, Func<TSource, int, bool> predicate)675 private static IEnumerable<TSource> SkipWhileYield<TSource>( 676 IEnumerable<TSource> source, 677 Func<TSource, int, bool> predicate) 678 { 679 using (var e = source.GetEnumerator()) 680 { 681 for (var i = 0;; i++) 682 { 683 if (!e.MoveNext()) 684 yield break; 685 686 if (!predicate(e.Current, i)) 687 break; 688 } 689 690 do 691 { 692 yield return e.Current; 693 } while (e.MoveNext()); 694 } 695 } 696 697 /// <summary> 698 /// Returns the number of elements in a sequence. 699 /// </summary> 700 Count( this IEnumerable<TSource> source)701 public static int Count<TSource>( 702 this IEnumerable<TSource> source) 703 { 704 CheckNotNull(source, "source"); 705 706 var collection = source as ICollection; 707 return collection != null 708 ? collection.Count 709 : source.Aggregate(0, (count, item) => checked(count + 1)); 710 } 711 712 /// <summary> 713 /// Returns a number that represents how many elements in the 714 /// specified sequence satisfy a condition. 715 /// </summary> 716 Count( this IEnumerable<TSource> source, Func<TSource, bool> predicate)717 public static int Count<TSource>( 718 this IEnumerable<TSource> source, 719 Func<TSource, bool> predicate) 720 { 721 return Count(source.Where(predicate)); 722 } 723 724 /// <summary> 725 /// Returns an <see cref="Int64"/> that represents the total number 726 /// of elements in a sequence. 727 /// </summary> 728 LongCount( this IEnumerable<TSource> source)729 public static long LongCount<TSource>( 730 this IEnumerable<TSource> source) 731 { 732 CheckNotNull(source, "source"); 733 734 var array = source as Array; 735 return array != null 736 ? array.LongLength 737 : source.Aggregate(0L, (count, item) => count + 1); 738 } 739 740 /// <summary> 741 /// Returns an <see cref="Int64"/> that represents how many elements 742 /// in a sequence satisfy a condition. 743 /// </summary> 744 LongCount( this IEnumerable<TSource> source, Func<TSource, bool> predicate)745 public static long LongCount<TSource>( 746 this IEnumerable<TSource> source, 747 Func<TSource, bool> predicate) 748 { 749 return LongCount(source.Where(predicate)); 750 } 751 752 /// <summary> 753 /// Concatenates two sequences. 754 /// </summary> 755 Concat( this IEnumerable<TSource> first, IEnumerable<TSource> second)756 public static IEnumerable<TSource> Concat<TSource>( 757 this IEnumerable<TSource> first, 758 IEnumerable<TSource> second) 759 { 760 CheckNotNull(first, "first"); 761 CheckNotNull(second, "second"); 762 763 return ConcatYield(first, second); 764 } 765 ConcatYield( IEnumerable<TSource> first, IEnumerable<TSource> second)766 private static IEnumerable<TSource> ConcatYield<TSource>( 767 IEnumerable<TSource> first, 768 IEnumerable<TSource> second) 769 { 770 foreach (var item in first) 771 yield return item; 772 773 foreach (var item in second) 774 yield return item; 775 } 776 777 /// <summary> 778 /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>. 779 /// </summary> 780 ToList( this IEnumerable<TSource> source)781 public static List<TSource> ToList<TSource>( 782 this IEnumerable<TSource> source) 783 { 784 CheckNotNull(source, "source"); 785 786 return new List<TSource>(source); 787 } 788 789 /// <summary> 790 /// Creates an array from an <see cref="IEnumerable{T}"/>. 791 /// </summary> 792 ToArray( this IEnumerable<TSource> source)793 public static TSource[] ToArray<TSource>( 794 this IEnumerable<TSource> source) 795 { 796 return source.ToList().ToArray(); 797 } 798 799 /// <summary> 800 /// Returns distinct elements from a sequence by using the default 801 /// equality comparer to compare values. 802 /// </summary> 803 Distinct( this IEnumerable<TSource> source)804 public static IEnumerable<TSource> Distinct<TSource>( 805 this IEnumerable<TSource> source) 806 { 807 return Distinct(source, /* comparer */ null); 808 } 809 810 /// <summary> 811 /// Returns distinct elements from a sequence by using a specified 812 /// <see cref="IEqualityComparer{T}"/> to compare values. 813 /// </summary> 814 Distinct( this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)815 public static IEnumerable<TSource> Distinct<TSource>( 816 this IEnumerable<TSource> source, 817 IEqualityComparer<TSource> comparer) 818 { 819 CheckNotNull(source, "source"); 820 821 return DistinctYield(source, comparer); 822 } 823 DistinctYield( IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)824 private static IEnumerable<TSource> DistinctYield<TSource>( 825 IEnumerable<TSource> source, 826 IEqualityComparer<TSource> comparer) 827 { 828 var set = new Dictionary<TSource, object>(comparer); 829 var gotNull = false; 830 831 foreach (var item in source) 832 { 833 if (item == null) 834 { 835 if (gotNull) 836 continue; 837 gotNull = true; 838 } 839 else 840 { 841 if (set.ContainsKey(item)) 842 continue; 843 set.Add(item, null); 844 } 845 846 yield return item; 847 } 848 } 849 850 /// <summary> 851 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 852 /// <see cref="IEnumerable{T}" /> according to a specified key 853 /// selector function. 854 /// </summary> 855 ToLookup( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)856 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>( 857 this IEnumerable<TSource> source, 858 Func<TSource, TKey> keySelector) 859 { 860 return ToLookup(source, keySelector, e => e, /* comparer */ null); 861 } 862 863 /// <summary> 864 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 865 /// <see cref="IEnumerable{T}" /> according to a specified key 866 /// selector function and a key comparer. 867 /// </summary> 868 ToLookup( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)869 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>( 870 this IEnumerable<TSource> source, 871 Func<TSource, TKey> keySelector, 872 IEqualityComparer<TKey> comparer) 873 { 874 return ToLookup(source, keySelector, e => e, comparer); 875 } 876 877 /// <summary> 878 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 879 /// <see cref="IEnumerable{T}" /> according to specified key 880 /// and element selector functions. 881 /// </summary> 882 ToLookup( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)883 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>( 884 this IEnumerable<TSource> source, 885 Func<TSource, TKey> keySelector, 886 Func<TSource, TElement> elementSelector) 887 { 888 return ToLookup(source, keySelector, elementSelector, /* comparer */ null); 889 } 890 891 /// <summary> 892 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an 893 /// <see cref="IEnumerable{T}" /> according to a specified key 894 /// selector function, a comparer and an element selector function. 895 /// </summary> 896 ToLookup( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)897 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>( 898 this IEnumerable<TSource> source, 899 Func<TSource, TKey> keySelector, 900 Func<TSource, TElement> elementSelector, 901 IEqualityComparer<TKey> comparer) 902 { 903 CheckNotNull(source, "source"); 904 CheckNotNull(keySelector, "keySelector"); 905 CheckNotNull(elementSelector, "elementSelector"); 906 907 var lookup = new Lookup<TKey, TElement>(comparer); 908 909 foreach (var item in source) 910 { 911 var key = keySelector(item); 912 913 var grouping = (Grouping<TKey, TElement>) lookup.Find(key); 914 if (grouping == null) 915 { 916 grouping = new Grouping<TKey, TElement>(key); 917 lookup.Add(grouping); 918 } 919 920 grouping.Add(elementSelector(item)); 921 } 922 923 return lookup; 924 } 925 926 /// <summary> 927 /// Groups the elements of a sequence according to a specified key 928 /// selector function. 929 /// </summary> 930 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)931 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( 932 this IEnumerable<TSource> source, 933 Func<TSource, TKey> keySelector) 934 { 935 return GroupBy(source, keySelector, /* comparer */ null); 936 } 937 938 /// <summary> 939 /// Groups the elements of a sequence according to a specified key 940 /// selector function and compares the keys by using a specified 941 /// comparer. 942 /// </summary> 943 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)944 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( 945 this IEnumerable<TSource> source, 946 Func<TSource, TKey> keySelector, 947 IEqualityComparer<TKey> comparer) 948 { 949 return GroupBy(source, keySelector, e => e, comparer); 950 } 951 952 /// <summary> 953 /// Groups the elements of a sequence according to a specified key 954 /// selector function and projects the elements for each group by 955 /// using a specified function. 956 /// </summary> 957 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)958 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>( 959 this IEnumerable<TSource> source, 960 Func<TSource, TKey> keySelector, 961 Func<TSource, TElement> elementSelector) 962 { 963 return GroupBy(source, keySelector, elementSelector, /* comparer */ null); 964 } 965 966 /// <summary> 967 /// Groups the elements of a sequence according to a specified key 968 /// selector function and creates a result value from each group and 969 /// its key. 970 /// </summary> 971 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)972 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>( 973 this IEnumerable<TSource> source, 974 Func<TSource, TKey> keySelector, 975 Func<TSource, TElement> elementSelector, 976 IEqualityComparer<TKey> comparer) 977 { 978 CheckNotNull(source, "source"); 979 CheckNotNull(keySelector, "keySelector"); 980 CheckNotNull(elementSelector, "elementSelector"); 981 982 return ToLookup(source, keySelector, elementSelector, comparer); 983 } 984 985 /// <summary> 986 /// Groups the elements of a sequence according to a key selector 987 /// function. The keys are compared by using a comparer and each 988 /// group's elements are projected by using a specified function. 989 /// </summary> 990 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector)991 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>( 992 this IEnumerable<TSource> source, 993 Func<TSource, TKey> keySelector, 994 Func<TKey, IEnumerable<TSource>, TResult> resultSelector) 995 { 996 return GroupBy(source, keySelector, resultSelector, /* comparer */ null); 997 } 998 999 /// <summary> 1000 /// Groups the elements of a sequence according to a specified key 1001 /// selector function and creates a result value from each group and 1002 /// its key. The elements of each group are projected by using a 1003 /// specified function. 1004 /// </summary> 1005 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer)1006 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>( 1007 this IEnumerable<TSource> source, 1008 Func<TSource, TKey> keySelector, 1009 Func<TKey, IEnumerable<TSource>, TResult> resultSelector, 1010 IEqualityComparer<TKey> comparer) 1011 { 1012 CheckNotNull(source, "source"); 1013 CheckNotNull(keySelector, "keySelector"); 1014 CheckNotNull(resultSelector, "resultSelector"); 1015 1016 return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g)); 1017 } 1018 1019 /// <summary> 1020 /// Groups the elements of a sequence according to a specified key 1021 /// selector function and creates a result value from each group and 1022 /// its key. The keys are compared by using a specified comparer. 1023 /// </summary> 1024 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector)1025 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>( 1026 this IEnumerable<TSource> source, 1027 Func<TSource, TKey> keySelector, 1028 Func<TSource, TElement> elementSelector, 1029 Func<TKey, IEnumerable<TElement>, TResult> resultSelector) 1030 { 1031 return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null); 1032 } 1033 1034 /// <summary> 1035 /// Groups the elements of a sequence according to a specified key 1036 /// selector function and creates a result value from each group and 1037 /// its key. Key values are compared by using a specified comparer, 1038 /// and the elements of each group are projected by using a 1039 /// specified function. 1040 /// </summary> 1041 GroupBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)1042 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>( 1043 this IEnumerable<TSource> source, 1044 Func<TSource, TKey> keySelector, 1045 Func<TSource, TElement> elementSelector, 1046 Func<TKey, IEnumerable<TElement>, TResult> resultSelector, 1047 IEqualityComparer<TKey> comparer) 1048 { 1049 CheckNotNull(source, "source"); 1050 CheckNotNull(keySelector, "keySelector"); 1051 CheckNotNull(elementSelector, "elementSelector"); 1052 CheckNotNull(resultSelector, "resultSelector"); 1053 1054 return ToLookup(source, keySelector, elementSelector, comparer) 1055 .Select(g => resultSelector(g.Key, g)); 1056 } 1057 1058 /// <summary> 1059 /// Applies an accumulator function over a sequence. 1060 /// </summary> 1061 Aggregate( this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)1062 public static TSource Aggregate<TSource>( 1063 this IEnumerable<TSource> source, 1064 Func<TSource, TSource, TSource> func) 1065 { 1066 CheckNotNull(source, "source"); 1067 CheckNotNull(func, "func"); 1068 1069 using (var e = source.GetEnumerator()) 1070 { 1071 if (!e.MoveNext()) 1072 throw new InvalidOperationException(); 1073 1074 return e.Renumerable().Skip(1).Aggregate(e.Current, func); 1075 } 1076 } 1077 1078 /// <summary> 1079 /// Applies an accumulator function over a sequence. The specified 1080 /// seed value is used as the initial accumulator value. 1081 /// </summary> 1082 Aggregate( this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)1083 public static TAccumulate Aggregate<TSource, TAccumulate>( 1084 this IEnumerable<TSource> source, 1085 TAccumulate seed, 1086 Func<TAccumulate, TSource, TAccumulate> func) 1087 { 1088 return Aggregate(source, seed, func, r => r); 1089 } 1090 1091 /// <summary> 1092 /// Applies an accumulator function over a sequence. The specified 1093 /// seed value is used as the initial accumulator value, and the 1094 /// specified function is used to select the result value. 1095 /// </summary> 1096 Aggregate( this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)1097 public static TResult Aggregate<TSource, TAccumulate, TResult>( 1098 this IEnumerable<TSource> source, 1099 TAccumulate seed, 1100 Func<TAccumulate, TSource, TAccumulate> func, 1101 Func<TAccumulate, TResult> resultSelector) 1102 { 1103 CheckNotNull(source, "source"); 1104 CheckNotNull(func, "func"); 1105 CheckNotNull(resultSelector, "resultSelector"); 1106 1107 var result = seed; 1108 1109 foreach (var item in source) 1110 result = func(result, item); 1111 1112 return resultSelector(result); 1113 } 1114 1115 /// <summary> 1116 /// Produces the set union of two sequences by using the default 1117 /// equality comparer. 1118 /// </summary> 1119 Union( this IEnumerable<TSource> first, IEnumerable<TSource> second)1120 public static IEnumerable<TSource> Union<TSource>( 1121 this IEnumerable<TSource> first, 1122 IEnumerable<TSource> second) 1123 { 1124 return Union(first, second, /* comparer */ null); 1125 } 1126 1127 /// <summary> 1128 /// Produces the set union of two sequences by using a specified 1129 /// <see cref="IEqualityComparer{T}" />. 1130 /// </summary> 1131 Union( this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)1132 public static IEnumerable<TSource> Union<TSource>( 1133 this IEnumerable<TSource> first, 1134 IEnumerable<TSource> second, 1135 IEqualityComparer<TSource> comparer) 1136 { 1137 return first.Concat(second).Distinct(comparer); 1138 } 1139 1140 /// <summary> 1141 /// Returns the elements of the specified sequence or the type 1142 /// parameter's default value in a singleton collection if the 1143 /// sequence is empty. 1144 /// </summary> 1145 DefaultIfEmpty( this IEnumerable<TSource> source)1146 public static IEnumerable<TSource> DefaultIfEmpty<TSource>( 1147 this IEnumerable<TSource> source) 1148 { 1149 return source.DefaultIfEmpty(default(TSource)); 1150 } 1151 1152 /// <summary> 1153 /// Returns the elements of the specified sequence or the specified 1154 /// value in a singleton collection if the sequence is empty. 1155 /// </summary> 1156 DefaultIfEmpty( this IEnumerable<TSource> source, TSource defaultValue)1157 public static IEnumerable<TSource> DefaultIfEmpty<TSource>( 1158 this IEnumerable<TSource> source, 1159 TSource defaultValue) 1160 { 1161 CheckNotNull(source, "source"); 1162 1163 return DefaultIfEmptyYield(source, defaultValue); 1164 } 1165 DefaultIfEmptyYield( IEnumerable<TSource> source, TSource defaultValue)1166 private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>( 1167 IEnumerable<TSource> source, 1168 TSource defaultValue) 1169 { 1170 using (var e = source.GetEnumerator()) 1171 { 1172 if (!e.MoveNext()) 1173 yield return defaultValue; 1174 else 1175 do 1176 { 1177 yield return e.Current; 1178 } while (e.MoveNext()); 1179 } 1180 } 1181 1182 /// <summary> 1183 /// Determines whether all elements of a sequence satisfy a condition. 1184 /// </summary> 1185 All( this IEnumerable<TSource> source, Func<TSource, bool> predicate)1186 public static bool All<TSource>( 1187 this IEnumerable<TSource> source, 1188 Func<TSource, bool> predicate) 1189 { 1190 CheckNotNull(source, "source"); 1191 CheckNotNull(predicate, "predicate"); 1192 1193 foreach (var item in source) 1194 if (!predicate(item)) 1195 return false; 1196 1197 return true; 1198 } 1199 1200 /// <summary> 1201 /// Determines whether a sequence contains any elements. 1202 /// </summary> 1203 Any( this IEnumerable<TSource> source)1204 public static bool Any<TSource>( 1205 this IEnumerable<TSource> source) 1206 { 1207 CheckNotNull(source, "source"); 1208 1209 using (var e = source.GetEnumerator()) 1210 return e.MoveNext(); 1211 } 1212 1213 /// <summary> 1214 /// Determines whether any element of a sequence satisfies a 1215 /// condition. 1216 /// </summary> 1217 Any( this IEnumerable<TSource> source, Func<TSource, bool> predicate)1218 public static bool Any<TSource>( 1219 this IEnumerable<TSource> source, 1220 Func<TSource, bool> predicate) 1221 { 1222 return source.Where(predicate).Any(); 1223 } 1224 1225 /// <summary> 1226 /// Determines whether a sequence contains a specified element by 1227 /// using the default equality comparer. 1228 /// </summary> 1229 Contains( this IEnumerable<TSource> source, TSource value)1230 public static bool Contains<TSource>( 1231 this IEnumerable<TSource> source, 1232 TSource value) 1233 { 1234 return source.Contains(value, /* comparer */ null); 1235 } 1236 1237 /// <summary> 1238 /// Determines whether a sequence contains a specified element by 1239 /// using a specified <see cref="IEqualityComparer{T}" />. 1240 /// </summary> 1241 Contains( this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)1242 public static bool Contains<TSource>( 1243 this IEnumerable<TSource> source, 1244 TSource value, 1245 IEqualityComparer<TSource> comparer) 1246 { 1247 CheckNotNull(source, "source"); 1248 1249 if (comparer == null) 1250 { 1251 var collection = source as ICollection<TSource>; 1252 if (collection != null) 1253 return collection.Contains(value); 1254 } 1255 1256 comparer = comparer ?? EqualityComparer<TSource>.Default; 1257 return source.Any(item => comparer.Equals(item, value)); 1258 } 1259 1260 /// <summary> 1261 /// Determines whether two sequences are equal by comparing the 1262 /// elements by using the default equality comparer for their type. 1263 /// </summary> 1264 SequenceEqual( this IEnumerable<TSource> first, IEnumerable<TSource> second)1265 public static bool SequenceEqual<TSource>( 1266 this IEnumerable<TSource> first, 1267 IEnumerable<TSource> second) 1268 { 1269 return first.SequenceEqual(second, /* comparer */ null); 1270 } 1271 1272 /// <summary> 1273 /// Determines whether two sequences are equal by comparing their 1274 /// elements by using a specified <see cref="IEqualityComparer{T}" />. 1275 /// </summary> 1276 SequenceEqual( this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)1277 public static bool SequenceEqual<TSource>( 1278 this IEnumerable<TSource> first, 1279 IEnumerable<TSource> second, 1280 IEqualityComparer<TSource> comparer) 1281 { 1282 CheckNotNull(first, "frist"); 1283 CheckNotNull(second, "second"); 1284 1285 comparer = comparer ?? EqualityComparer<TSource>.Default; 1286 1287 using (IEnumerator<TSource> lhs = first.GetEnumerator(), 1288 rhs = second.GetEnumerator()) 1289 { 1290 do 1291 { 1292 if (!lhs.MoveNext()) 1293 return !rhs.MoveNext(); 1294 1295 if (!rhs.MoveNext()) 1296 return false; 1297 } while (comparer.Equals(lhs.Current, rhs.Current)); 1298 } 1299 1300 return false; 1301 } 1302 1303 /// <summary> 1304 /// Base implementation for Min/Max operator. 1305 /// </summary> 1306 MinMaxImpl( this IEnumerable<TSource> source, Func<TSource, TSource, bool> lesser)1307 private static TSource MinMaxImpl<TSource>( 1308 this IEnumerable<TSource> source, 1309 Func<TSource, TSource, bool> lesser) 1310 { 1311 CheckNotNull(source, "source"); 1312 Debug.Assert(lesser != null); 1313 1314 return source.Aggregate((a, item) => lesser(a, item) ? a : item); 1315 } 1316 1317 /// <summary> 1318 /// Base implementation for Min/Max operator for nullable types. 1319 /// </summary> 1320 1321 private static TSource? MinMaxImpl<TSource>( 1322 this IEnumerable<TSource?> source, 1323 TSource? seed, Func<TSource?, TSource?, bool> lesser) where TSource : struct 1324 { CheckNotNullNewtonsoft.Json.Utilities.LinqBridge.Enumerable.__anon11325 CheckNotNull(source, "source"); 1326 Debug.Assert(lesser != null); 1327 1328 return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item); 1329 // == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser); 1330 } 1331 1332 /// <summary> 1333 /// Returns the minimum value in a generic sequence. 1334 /// </summary> 1335 Min( this IEnumerable<TSource> source)1336 public static TSource Min<TSource>( 1337 this IEnumerable<TSource> source) 1338 { 1339 var comparer = Comparer<TSource>.Default; 1340 return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0); 1341 } 1342 1343 /// <summary> 1344 /// Invokes a transform function on each element of a generic 1345 /// sequence and returns the minimum resulting value. 1346 /// </summary> 1347 Min( this IEnumerable<TSource> source, Func<TSource, TResult> selector)1348 public static TResult Min<TSource, TResult>( 1349 this IEnumerable<TSource> source, 1350 Func<TSource, TResult> selector) 1351 { 1352 return source.Select(selector).Min(); 1353 } 1354 1355 /// <summary> 1356 /// Returns the maximum value in a generic sequence. 1357 /// </summary> 1358 Max( this IEnumerable<TSource> source)1359 public static TSource Max<TSource>( 1360 this IEnumerable<TSource> source) 1361 { 1362 var comparer = Comparer<TSource>.Default; 1363 return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0); 1364 } 1365 1366 /// <summary> 1367 /// Invokes a transform function on each element of a generic 1368 /// sequence and returns the maximum resulting value. 1369 /// </summary> 1370 Max( this IEnumerable<TSource> source, Func<TSource, TResult> selector)1371 public static TResult Max<TSource, TResult>( 1372 this IEnumerable<TSource> source, 1373 Func<TSource, TResult> selector) 1374 { 1375 return source.Select(selector).Max(); 1376 } 1377 1378 /// <summary> 1379 /// Makes an enumerator seen as enumerable once more. 1380 /// </summary> 1381 /// <remarks> 1382 /// The supplied enumerator must have been started. The first element 1383 /// returned is the element the enumerator was on when passed in. 1384 /// DO NOT use this method if the caller must be a generator. It is 1385 /// mostly safe among aggregate operations. 1386 /// </remarks> 1387 Renumerable(this IEnumerator<T> e)1388 private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e) 1389 { 1390 Debug.Assert(e != null); 1391 1392 do 1393 { 1394 yield return e.Current; 1395 } while (e.MoveNext()); 1396 } 1397 1398 /// <summary> 1399 /// Sorts the elements of a sequence in ascending order according to a key. 1400 /// </summary> 1401 OrderBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)1402 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( 1403 this IEnumerable<TSource> source, 1404 Func<TSource, TKey> keySelector) 1405 { 1406 return source.OrderBy(keySelector, /* comparer */ null); 1407 } 1408 1409 /// <summary> 1410 /// Sorts the elements of a sequence in ascending order by using a 1411 /// specified comparer. 1412 /// </summary> 1413 OrderBy( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)1414 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( 1415 this IEnumerable<TSource> source, 1416 Func<TSource, TKey> keySelector, 1417 IComparer<TKey> comparer) 1418 { 1419 CheckNotNull(source, "source"); 1420 CheckNotNull(keySelector, "keySelector"); 1421 1422 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false); 1423 } 1424 1425 /// <summary> 1426 /// Sorts the elements of a sequence in descending order according to a key. 1427 /// </summary> 1428 OrderByDescending( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)1429 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>( 1430 this IEnumerable<TSource> source, 1431 Func<TSource, TKey> keySelector) 1432 { 1433 return source.OrderByDescending(keySelector, /* comparer */ null); 1434 } 1435 1436 /// <summary> 1437 /// Sorts the elements of a sequence in descending order by using a 1438 /// specified comparer. 1439 /// </summary> 1440 OrderByDescending( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)1441 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>( 1442 this IEnumerable<TSource> source, 1443 Func<TSource, TKey> keySelector, 1444 IComparer<TKey> comparer) 1445 { 1446 CheckNotNull(source, "source"); 1447 CheckNotNull(source, "keySelector"); 1448 1449 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true); 1450 } 1451 1452 /// <summary> 1453 /// Performs a subsequent ordering of the elements in a sequence in 1454 /// ascending order according to a key. 1455 /// </summary> 1456 ThenBy( this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)1457 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>( 1458 this IOrderedEnumerable<TSource> source, 1459 Func<TSource, TKey> keySelector) 1460 { 1461 return source.ThenBy(keySelector, /* comparer */ null); 1462 } 1463 1464 /// <summary> 1465 /// Performs a subsequent ordering of the elements in a sequence in 1466 /// ascending order by using a specified comparer. 1467 /// </summary> 1468 ThenBy( this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)1469 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>( 1470 this IOrderedEnumerable<TSource> source, 1471 Func<TSource, TKey> keySelector, 1472 IComparer<TKey> comparer) 1473 { 1474 CheckNotNull(source, "source"); 1475 1476 return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false); 1477 } 1478 1479 /// <summary> 1480 /// Performs a subsequent ordering of the elements in a sequence in 1481 /// descending order, according to a key. 1482 /// </summary> 1483 ThenByDescending( this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector)1484 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>( 1485 this IOrderedEnumerable<TSource> source, 1486 Func<TSource, TKey> keySelector) 1487 { 1488 return source.ThenByDescending(keySelector, /* comparer */ null); 1489 } 1490 1491 /// <summary> 1492 /// Performs a subsequent ordering of the elements in a sequence in 1493 /// descending order by using a specified comparer. 1494 /// </summary> 1495 ThenByDescending( this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)1496 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>( 1497 this IOrderedEnumerable<TSource> source, 1498 Func<TSource, TKey> keySelector, 1499 IComparer<TKey> comparer) 1500 { 1501 CheckNotNull(source, "source"); 1502 1503 return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true); 1504 } 1505 1506 /// <summary> 1507 /// Base implementation for Intersect and Except operators. 1508 /// </summary> 1509 IntersectExceptImpl( this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer, bool flag)1510 private static IEnumerable<TSource> IntersectExceptImpl<TSource>( 1511 this IEnumerable<TSource> first, 1512 IEnumerable<TSource> second, 1513 IEqualityComparer<TSource> comparer, 1514 bool flag) 1515 { 1516 CheckNotNull(first, "first"); 1517 CheckNotNull(second, "second"); 1518 1519 var keys = new List<TSource>(); 1520 var flags = new Dictionary<TSource, bool>(comparer); 1521 1522 foreach (var item in first.Where(k => !flags.ContainsKey(k))) 1523 { 1524 flags.Add(item, !flag); 1525 keys.Add(item); 1526 } 1527 1528 foreach (var item in second.Where(flags.ContainsKey)) 1529 flags[item] = flag; 1530 1531 // 1532 // As per docs, "the marked elements are yielded in the order in 1533 // which they were collected. 1534 // 1535 1536 return keys.Where(item => flags[item]); 1537 } 1538 1539 /// <summary> 1540 /// Produces the set intersection of two sequences by using the 1541 /// default equality comparer to compare values. 1542 /// </summary> 1543 Intersect( this IEnumerable<TSource> first, IEnumerable<TSource> second)1544 public static IEnumerable<TSource> Intersect<TSource>( 1545 this IEnumerable<TSource> first, 1546 IEnumerable<TSource> second) 1547 { 1548 return first.Intersect(second, /* comparer */ null); 1549 } 1550 1551 /// <summary> 1552 /// Produces the set intersection of two sequences by using the 1553 /// specified <see cref="IEqualityComparer{T}" /> to compare values. 1554 /// </summary> 1555 Intersect( this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)1556 public static IEnumerable<TSource> Intersect<TSource>( 1557 this IEnumerable<TSource> first, 1558 IEnumerable<TSource> second, 1559 IEqualityComparer<TSource> comparer) 1560 { 1561 return IntersectExceptImpl(first, second, comparer, /* flag */ true); 1562 } 1563 1564 /// <summary> 1565 /// Produces the set difference of two sequences by using the 1566 /// default equality comparer to compare values. 1567 /// </summary> 1568 Except( this IEnumerable<TSource> first, IEnumerable<TSource> second)1569 public static IEnumerable<TSource> Except<TSource>( 1570 this IEnumerable<TSource> first, 1571 IEnumerable<TSource> second) 1572 { 1573 return first.Except(second, /* comparer */ null); 1574 } 1575 1576 /// <summary> 1577 /// Produces the set difference of two sequences by using the 1578 /// specified <see cref="IEqualityComparer{T}" /> to compare values. 1579 /// </summary> 1580 Except( this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)1581 public static IEnumerable<TSource> Except<TSource>( 1582 this IEnumerable<TSource> first, 1583 IEnumerable<TSource> second, 1584 IEqualityComparer<TSource> comparer) 1585 { 1586 return IntersectExceptImpl(first, second, comparer, /* flag */ false); 1587 } 1588 1589 /// <summary> 1590 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 1591 /// <see cref="IEnumerable{T}" /> according to a specified key 1592 /// selector function. 1593 /// </summary> 1594 ToDictionary( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)1595 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>( 1596 this IEnumerable<TSource> source, 1597 Func<TSource, TKey> keySelector) 1598 { 1599 return source.ToDictionary(keySelector, /* comparer */ null); 1600 } 1601 1602 /// <summary> 1603 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 1604 /// <see cref="IEnumerable{T}" /> according to a specified key 1605 /// selector function and key comparer. 1606 /// </summary> 1607 ToDictionary( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)1608 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>( 1609 this IEnumerable<TSource> source, 1610 Func<TSource, TKey> keySelector, 1611 IEqualityComparer<TKey> comparer) 1612 { 1613 return source.ToDictionary(keySelector, e => e); 1614 } 1615 1616 /// <summary> 1617 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 1618 /// <see cref="IEnumerable{T}" /> according to specified key 1619 /// selector and element selector functions. 1620 /// </summary> 1621 ToDictionary( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)1622 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>( 1623 this IEnumerable<TSource> source, 1624 Func<TSource, TKey> keySelector, 1625 Func<TSource, TElement> elementSelector) 1626 { 1627 return source.ToDictionary(keySelector, elementSelector, /* comparer */ null); 1628 } 1629 1630 /// <summary> 1631 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an 1632 /// <see cref="IEnumerable{T}" /> according to a specified key 1633 /// selector function, a comparer, and an element selector function. 1634 /// </summary> 1635 ToDictionary( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)1636 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>( 1637 this IEnumerable<TSource> source, 1638 Func<TSource, TKey> keySelector, 1639 Func<TSource, TElement> elementSelector, 1640 IEqualityComparer<TKey> comparer) 1641 { 1642 CheckNotNull(source, "source"); 1643 CheckNotNull(keySelector, "keySelector"); 1644 CheckNotNull(elementSelector, "elementSelector"); 1645 1646 var dict = new Dictionary<TKey, TElement>(comparer); 1647 1648 foreach (var item in source) 1649 { 1650 // 1651 // ToDictionary is meant to throw ArgumentNullException if 1652 // keySelector produces a key that is null and 1653 // Argument exception if keySelector produces duplicate keys 1654 // for two elements. Incidentally, the doucmentation for 1655 // IDictionary<TKey, TValue>.Add says that the Add method 1656 // throws the same exceptions under the same circumstances 1657 // so we don't need to do any additional checking or work 1658 // here and let the Add implementation do all the heavy 1659 // lifting. 1660 // 1661 1662 dict.Add(keySelector(item), elementSelector(item)); 1663 } 1664 1665 return dict; 1666 } 1667 1668 /// <summary> 1669 /// Correlates the elements of two sequences based on matching keys. 1670 /// The default equality comparer is used to compare keys. 1671 /// </summary> 1672 Join( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)1673 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( 1674 this IEnumerable<TOuter> outer, 1675 IEnumerable<TInner> inner, 1676 Func<TOuter, TKey> outerKeySelector, 1677 Func<TInner, TKey> innerKeySelector, 1678 Func<TOuter, TInner, TResult> resultSelector) 1679 { 1680 return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null); 1681 } 1682 1683 /// <summary> 1684 /// Correlates the elements of two sequences based on matching keys. 1685 /// The default equality comparer is used to compare keys. A 1686 /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys. 1687 /// </summary> 1688 Join( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)1689 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( 1690 this IEnumerable<TOuter> outer, 1691 IEnumerable<TInner> inner, 1692 Func<TOuter, TKey> outerKeySelector, 1693 Func<TInner, TKey> innerKeySelector, 1694 Func<TOuter, TInner, TResult> resultSelector, 1695 IEqualityComparer<TKey> comparer) 1696 { 1697 CheckNotNull(outer, "outer"); 1698 CheckNotNull(inner, "inner"); 1699 CheckNotNull(outerKeySelector, "outerKeySelector"); 1700 CheckNotNull(innerKeySelector, "innerKeySelector"); 1701 CheckNotNull(resultSelector, "resultSelector"); 1702 1703 var lookup = inner.ToLookup(innerKeySelector, comparer); 1704 1705 return 1706 from o in outer 1707 from i in lookup[outerKeySelector(o)] 1708 select resultSelector(o, i); 1709 } 1710 1711 /// <summary> 1712 /// Correlates the elements of two sequences based on equality of 1713 /// keys and groups the results. The default equality comparer is 1714 /// used to compare keys. 1715 /// </summary> 1716 GroupJoin( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)1717 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>( 1718 this IEnumerable<TOuter> outer, 1719 IEnumerable<TInner> inner, 1720 Func<TOuter, TKey> outerKeySelector, 1721 Func<TInner, TKey> innerKeySelector, 1722 Func<TOuter, IEnumerable<TInner>, TResult> resultSelector) 1723 { 1724 return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null); 1725 } 1726 1727 /// <summary> 1728 /// Correlates the elements of two sequences based on equality of 1729 /// keys and groups the results. The default equality comparer is 1730 /// used to compare keys. A specified <see cref="IEqualityComparer{T}" /> 1731 /// is used to compare keys. 1732 /// </summary> 1733 GroupJoin( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer)1734 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>( 1735 this IEnumerable<TOuter> outer, 1736 IEnumerable<TInner> inner, 1737 Func<TOuter, TKey> outerKeySelector, 1738 Func<TInner, TKey> innerKeySelector, 1739 Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, 1740 IEqualityComparer<TKey> comparer) 1741 { 1742 CheckNotNull(outer, "outer"); 1743 CheckNotNull(inner, "inner"); 1744 CheckNotNull(outerKeySelector, "outerKeySelector"); 1745 CheckNotNull(innerKeySelector, "innerKeySelector"); 1746 CheckNotNull(resultSelector, "resultSelector"); 1747 1748 var lookup = inner.ToLookup(innerKeySelector, comparer); 1749 return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)])); 1750 } 1751 1752 [DebuggerStepThrough] 1753 private static void CheckNotNull<T>(T value, string name) where T : class 1754 { 1755 if (value == null) ArgumentNullException(name)1756 throw new ArgumentNullException(name); 1757 } 1758 1759 private static class Sequence<T> 1760 { 1761 public static readonly IEnumerable<T> Empty = new T[0]; 1762 } 1763 1764 private sealed class Grouping<K, V> : List<V>, IGrouping<K, V> 1765 { Grouping(K key)1766 internal Grouping(K key) 1767 { 1768 Key = key; 1769 } 1770 1771 public K Key { get; private set; } 1772 } 1773 } 1774 1775 internal partial class Enumerable 1776 { 1777 /// <summary> 1778 /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values. 1779 /// </summary> 1780 Sum( this IEnumerable<int> source)1781 public static int Sum( 1782 this IEnumerable<int> source) 1783 { 1784 CheckNotNull(source, "source"); 1785 1786 int sum = 0; 1787 foreach (var num in source) 1788 sum = checked(sum + num); 1789 1790 return sum; 1791 } 1792 1793 /// <summary> 1794 /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> 1795 /// values that are obtained by invoking a transform function on 1796 /// each element of the input sequence. 1797 /// </summary> 1798 Sum( this IEnumerable<TSource> source, Func<TSource, int> selector)1799 public static int Sum<TSource>( 1800 this IEnumerable<TSource> source, 1801 Func<TSource, int> selector) 1802 { 1803 return source.Select(selector).Sum(); 1804 } 1805 1806 /// <summary> 1807 /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values. 1808 /// </summary> 1809 Average( this IEnumerable<int> source)1810 public static double Average( 1811 this IEnumerable<int> source) 1812 { 1813 CheckNotNull(source, "source"); 1814 1815 long sum = 0; 1816 long count = 0; 1817 1818 foreach (var num in source) 1819 checked 1820 { 1821 sum += (int) num; 1822 count++; 1823 } 1824 1825 if (count == 0) 1826 throw new InvalidOperationException(); 1827 1828 return (double) sum/count; 1829 } 1830 1831 /// <summary> 1832 /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values 1833 /// that are obtained by invoking a transform function on each 1834 /// element of the input sequence. 1835 /// </summary> 1836 Average( this IEnumerable<TSource> source, Func<TSource, int> selector)1837 public static double Average<TSource>( 1838 this IEnumerable<TSource> source, 1839 Func<TSource, int> selector) 1840 { 1841 return source.Select(selector).Average(); 1842 } 1843 1844 1845 /// <summary> 1846 /// Computes the sum of a sequence of <see cref="System.Int32" /> values. 1847 /// </summary> 1848 Sum( this IEnumerable<int?> source)1849 public static int? Sum( 1850 this IEnumerable<int?> source) 1851 { 1852 CheckNotNull(source, "source"); 1853 1854 int sum = 0; 1855 foreach (var num in source) 1856 sum = checked(sum + (num ?? 0)); 1857 1858 return sum; 1859 } 1860 1861 /// <summary> 1862 /// Computes the sum of a sequence of <see cref="System.Int32" /> 1863 /// values that are obtained by invoking a transform function on 1864 /// each element of the input sequence. 1865 /// </summary> 1866 Sum( this IEnumerable<TSource> source, Func<TSource, int?> selector)1867 public static int? Sum<TSource>( 1868 this IEnumerable<TSource> source, 1869 Func<TSource, int?> selector) 1870 { 1871 return source.Select(selector).Sum(); 1872 } 1873 1874 /// <summary> 1875 /// Computes the average of a sequence of <see cref="System.Int32" /> values. 1876 /// </summary> 1877 Average( this IEnumerable<int?> source)1878 public static double? Average( 1879 this IEnumerable<int?> source) 1880 { 1881 CheckNotNull(source, "source"); 1882 1883 long sum = 0; 1884 long count = 0; 1885 1886 foreach (var num in source.Where(n => n != null)) 1887 checked 1888 { 1889 sum += (int) num; 1890 count++; 1891 } 1892 1893 if (count == 0) 1894 return null; 1895 1896 return (double?) sum/count; 1897 } 1898 1899 /// <summary> 1900 /// Computes the average of a sequence of <see cref="System.Int32" /> values 1901 /// that are obtained by invoking a transform function on each 1902 /// element of the input sequence. 1903 /// </summary> 1904 Average( this IEnumerable<TSource> source, Func<TSource, int?> selector)1905 public static double? Average<TSource>( 1906 this IEnumerable<TSource> source, 1907 Func<TSource, int?> selector) 1908 { 1909 return source.Select(selector).Average(); 1910 } 1911 1912 /// <summary> 1913 /// Returns the minimum value in a sequence of nullable 1914 /// <see cref="System.Int32" /> values. 1915 /// </summary> 1916 Min( this IEnumerable<int?> source)1917 public static int? Min( 1918 this IEnumerable<int?> source) 1919 { 1920 CheckNotNull(source, "source"); 1921 1922 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); 1923 } 1924 1925 /// <summary> 1926 /// Invokes a transform function on each element of a sequence and 1927 /// returns the minimum nullable <see cref="System.Int32" /> value. 1928 /// </summary> 1929 Min( this IEnumerable<TSource> source, Func<TSource, int?> selector)1930 public static int? Min<TSource>( 1931 this IEnumerable<TSource> source, 1932 Func<TSource, int?> selector) 1933 { 1934 return source.Select(selector).Min(); 1935 } 1936 1937 /// <summary> 1938 /// Returns the maximum value in a sequence of nullable 1939 /// <see cref="System.Int32" /> values. 1940 /// </summary> 1941 Max( this IEnumerable<int?> source)1942 public static int? Max( 1943 this IEnumerable<int?> source) 1944 { 1945 CheckNotNull(source, "source"); 1946 1947 return MinMaxImpl(source.Where(x => x != null), 1948 null, (max, x) => x == null || (max != null && x.Value < max.Value)); 1949 } 1950 1951 /// <summary> 1952 /// Invokes a transform function on each element of a sequence and 1953 /// returns the maximum nullable <see cref="System.Int32" /> value. 1954 /// </summary> 1955 Max( this IEnumerable<TSource> source, Func<TSource, int?> selector)1956 public static int? Max<TSource>( 1957 this IEnumerable<TSource> source, 1958 Func<TSource, int?> selector) 1959 { 1960 return source.Select(selector).Max(); 1961 } 1962 1963 /// <summary> 1964 /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values. 1965 /// </summary> 1966 Sum( this IEnumerable<long> source)1967 public static long Sum( 1968 this IEnumerable<long> source) 1969 { 1970 CheckNotNull(source, "source"); 1971 1972 long sum = 0; 1973 foreach (var num in source) 1974 sum = checked(sum + num); 1975 1976 return sum; 1977 } 1978 1979 /// <summary> 1980 /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> 1981 /// values that are obtained by invoking a transform function on 1982 /// each element of the input sequence. 1983 /// </summary> 1984 Sum( this IEnumerable<TSource> source, Func<TSource, long> selector)1985 public static long Sum<TSource>( 1986 this IEnumerable<TSource> source, 1987 Func<TSource, long> selector) 1988 { 1989 return source.Select(selector).Sum(); 1990 } 1991 1992 /// <summary> 1993 /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values. 1994 /// </summary> 1995 Average( this IEnumerable<long> source)1996 public static double Average( 1997 this IEnumerable<long> source) 1998 { 1999 CheckNotNull(source, "source"); 2000 2001 long sum = 0; 2002 long count = 0; 2003 2004 foreach (var num in source) 2005 checked 2006 { 2007 sum += (long) num; 2008 count++; 2009 } 2010 2011 if (count == 0) 2012 throw new InvalidOperationException(); 2013 2014 return (double) sum/count; 2015 } 2016 2017 /// <summary> 2018 /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values 2019 /// that are obtained by invoking a transform function on each 2020 /// element of the input sequence. 2021 /// </summary> 2022 Average( this IEnumerable<TSource> source, Func<TSource, long> selector)2023 public static double Average<TSource>( 2024 this IEnumerable<TSource> source, 2025 Func<TSource, long> selector) 2026 { 2027 return source.Select(selector).Average(); 2028 } 2029 2030 2031 /// <summary> 2032 /// Computes the sum of a sequence of <see cref="System.Int64" /> values. 2033 /// </summary> 2034 Sum( this IEnumerable<long?> source)2035 public static long? Sum( 2036 this IEnumerable<long?> source) 2037 { 2038 CheckNotNull(source, "source"); 2039 2040 long sum = 0; 2041 foreach (var num in source) 2042 sum = checked(sum + (num ?? 0)); 2043 2044 return sum; 2045 } 2046 2047 /// <summary> 2048 /// Computes the sum of a sequence of <see cref="System.Int64" /> 2049 /// values that are obtained by invoking a transform function on 2050 /// each element of the input sequence. 2051 /// </summary> 2052 Sum( this IEnumerable<TSource> source, Func<TSource, long?> selector)2053 public static long? Sum<TSource>( 2054 this IEnumerable<TSource> source, 2055 Func<TSource, long?> selector) 2056 { 2057 return source.Select(selector).Sum(); 2058 } 2059 2060 /// <summary> 2061 /// Computes the average of a sequence of <see cref="System.Int64" /> values. 2062 /// </summary> 2063 Average( this IEnumerable<long?> source)2064 public static double? Average( 2065 this IEnumerable<long?> source) 2066 { 2067 CheckNotNull(source, "source"); 2068 2069 long sum = 0; 2070 long count = 0; 2071 2072 foreach (var num in source.Where(n => n != null)) 2073 checked 2074 { 2075 sum += (long) num; 2076 count++; 2077 } 2078 2079 if (count == 0) 2080 return null; 2081 2082 return (double?) sum/count; 2083 } 2084 2085 /// <summary> 2086 /// Computes the average of a sequence of <see cref="System.Int64" /> values 2087 /// that are obtained by invoking a transform function on each 2088 /// element of the input sequence. 2089 /// </summary> 2090 Average( this IEnumerable<TSource> source, Func<TSource, long?> selector)2091 public static double? Average<TSource>( 2092 this IEnumerable<TSource> source, 2093 Func<TSource, long?> selector) 2094 { 2095 return source.Select(selector).Average(); 2096 } 2097 2098 /// <summary> 2099 /// Returns the minimum value in a sequence of nullable 2100 /// <see cref="System.Int64" /> values. 2101 /// </summary> 2102 Min( this IEnumerable<long?> source)2103 public static long? Min( 2104 this IEnumerable<long?> source) 2105 { 2106 CheckNotNull(source, "source"); 2107 2108 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); 2109 } 2110 2111 /// <summary> 2112 /// Invokes a transform function on each element of a sequence and 2113 /// returns the minimum nullable <see cref="System.Int64" /> value. 2114 /// </summary> 2115 Min( this IEnumerable<TSource> source, Func<TSource, long?> selector)2116 public static long? Min<TSource>( 2117 this IEnumerable<TSource> source, 2118 Func<TSource, long?> selector) 2119 { 2120 return source.Select(selector).Min(); 2121 } 2122 2123 /// <summary> 2124 /// Returns the maximum value in a sequence of nullable 2125 /// <see cref="System.Int64" /> values. 2126 /// </summary> 2127 Max( this IEnumerable<long?> source)2128 public static long? Max( 2129 this IEnumerable<long?> source) 2130 { 2131 CheckNotNull(source, "source"); 2132 2133 return MinMaxImpl(source.Where(x => x != null), 2134 null, (max, x) => x == null || (max != null && x.Value < max.Value)); 2135 } 2136 2137 /// <summary> 2138 /// Invokes a transform function on each element of a sequence and 2139 /// returns the maximum nullable <see cref="System.Int64" /> value. 2140 /// </summary> 2141 Max( this IEnumerable<TSource> source, Func<TSource, long?> selector)2142 public static long? Max<TSource>( 2143 this IEnumerable<TSource> source, 2144 Func<TSource, long?> selector) 2145 { 2146 return source.Select(selector).Max(); 2147 } 2148 2149 /// <summary> 2150 /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values. 2151 /// </summary> 2152 Sum( this IEnumerable<float> source)2153 public static float Sum( 2154 this IEnumerable<float> source) 2155 { 2156 CheckNotNull(source, "source"); 2157 2158 float sum = 0; 2159 foreach (var num in source) 2160 sum = checked(sum + num); 2161 2162 return sum; 2163 } 2164 2165 /// <summary> 2166 /// Computes the sum of a sequence of nullable <see cref="System.Single" /> 2167 /// values that are obtained by invoking a transform function on 2168 /// each element of the input sequence. 2169 /// </summary> 2170 Sum( this IEnumerable<TSource> source, Func<TSource, float> selector)2171 public static float Sum<TSource>( 2172 this IEnumerable<TSource> source, 2173 Func<TSource, float> selector) 2174 { 2175 return source.Select(selector).Sum(); 2176 } 2177 2178 /// <summary> 2179 /// Computes the average of a sequence of nullable <see cref="System.Single" /> values. 2180 /// </summary> 2181 Average( this IEnumerable<float> source)2182 public static float Average( 2183 this IEnumerable<float> source) 2184 { 2185 CheckNotNull(source, "source"); 2186 2187 float sum = 0; 2188 long count = 0; 2189 2190 foreach (var num in source) 2191 checked 2192 { 2193 sum += (float) num; 2194 count++; 2195 } 2196 2197 if (count == 0) 2198 throw new InvalidOperationException(); 2199 2200 return (float) sum/count; 2201 } 2202 2203 /// <summary> 2204 /// Computes the average of a sequence of nullable <see cref="System.Single" /> values 2205 /// that are obtained by invoking a transform function on each 2206 /// element of the input sequence. 2207 /// </summary> 2208 Average( this IEnumerable<TSource> source, Func<TSource, float> selector)2209 public static float Average<TSource>( 2210 this IEnumerable<TSource> source, 2211 Func<TSource, float> selector) 2212 { 2213 return source.Select(selector).Average(); 2214 } 2215 2216 2217 /// <summary> 2218 /// Computes the sum of a sequence of <see cref="System.Single" /> values. 2219 /// </summary> 2220 Sum( this IEnumerable<float?> source)2221 public static float? Sum( 2222 this IEnumerable<float?> source) 2223 { 2224 CheckNotNull(source, "source"); 2225 2226 float sum = 0; 2227 foreach (var num in source) 2228 sum = checked(sum + (num ?? 0)); 2229 2230 return sum; 2231 } 2232 2233 /// <summary> 2234 /// Computes the sum of a sequence of <see cref="System.Single" /> 2235 /// values that are obtained by invoking a transform function on 2236 /// each element of the input sequence. 2237 /// </summary> 2238 Sum( this IEnumerable<TSource> source, Func<TSource, float?> selector)2239 public static float? Sum<TSource>( 2240 this IEnumerable<TSource> source, 2241 Func<TSource, float?> selector) 2242 { 2243 return source.Select(selector).Sum(); 2244 } 2245 2246 /// <summary> 2247 /// Computes the average of a sequence of <see cref="System.Single" /> values. 2248 /// </summary> 2249 Average( this IEnumerable<float?> source)2250 public static float? Average( 2251 this IEnumerable<float?> source) 2252 { 2253 CheckNotNull(source, "source"); 2254 2255 float sum = 0; 2256 long count = 0; 2257 2258 foreach (var num in source.Where(n => n != null)) 2259 checked 2260 { 2261 sum += (float) num; 2262 count++; 2263 } 2264 2265 if (count == 0) 2266 return null; 2267 2268 return (float?) sum/count; 2269 } 2270 2271 /// <summary> 2272 /// Computes the average of a sequence of <see cref="System.Single" /> values 2273 /// that are obtained by invoking a transform function on each 2274 /// element of the input sequence. 2275 /// </summary> 2276 Average( this IEnumerable<TSource> source, Func<TSource, float?> selector)2277 public static float? Average<TSource>( 2278 this IEnumerable<TSource> source, 2279 Func<TSource, float?> selector) 2280 { 2281 return source.Select(selector).Average(); 2282 } 2283 2284 /// <summary> 2285 /// Returns the minimum value in a sequence of nullable 2286 /// <see cref="System.Single" /> values. 2287 /// </summary> 2288 Min( this IEnumerable<float?> source)2289 public static float? Min( 2290 this IEnumerable<float?> source) 2291 { 2292 CheckNotNull(source, "source"); 2293 2294 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); 2295 } 2296 2297 /// <summary> 2298 /// Invokes a transform function on each element of a sequence and 2299 /// returns the minimum nullable <see cref="System.Single" /> value. 2300 /// </summary> 2301 Min( this IEnumerable<TSource> source, Func<TSource, float?> selector)2302 public static float? Min<TSource>( 2303 this IEnumerable<TSource> source, 2304 Func<TSource, float?> selector) 2305 { 2306 return source.Select(selector).Min(); 2307 } 2308 2309 /// <summary> 2310 /// Returns the maximum value in a sequence of nullable 2311 /// <see cref="System.Single" /> values. 2312 /// </summary> 2313 Max( this IEnumerable<float?> source)2314 public static float? Max( 2315 this IEnumerable<float?> source) 2316 { 2317 CheckNotNull(source, "source"); 2318 2319 return MinMaxImpl(source.Where(x => x != null), 2320 null, (max, x) => x == null || (max != null && x.Value < max.Value)); 2321 } 2322 2323 /// <summary> 2324 /// Invokes a transform function on each element of a sequence and 2325 /// returns the maximum nullable <see cref="System.Single" /> value. 2326 /// </summary> 2327 Max( this IEnumerable<TSource> source, Func<TSource, float?> selector)2328 public static float? Max<TSource>( 2329 this IEnumerable<TSource> source, 2330 Func<TSource, float?> selector) 2331 { 2332 return source.Select(selector).Max(); 2333 } 2334 2335 /// <summary> 2336 /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values. 2337 /// </summary> 2338 Sum( this IEnumerable<double> source)2339 public static double Sum( 2340 this IEnumerable<double> source) 2341 { 2342 CheckNotNull(source, "source"); 2343 2344 double sum = 0; 2345 foreach (var num in source) 2346 sum = checked(sum + num); 2347 2348 return sum; 2349 } 2350 2351 /// <summary> 2352 /// Computes the sum of a sequence of nullable <see cref="System.Double" /> 2353 /// values that are obtained by invoking a transform function on 2354 /// each element of the input sequence. 2355 /// </summary> 2356 Sum( this IEnumerable<TSource> source, Func<TSource, double> selector)2357 public static double Sum<TSource>( 2358 this IEnumerable<TSource> source, 2359 Func<TSource, double> selector) 2360 { 2361 return source.Select(selector).Sum(); 2362 } 2363 2364 /// <summary> 2365 /// Computes the average of a sequence of nullable <see cref="System.Double" /> values. 2366 /// </summary> 2367 Average( this IEnumerable<double> source)2368 public static double Average( 2369 this IEnumerable<double> source) 2370 { 2371 CheckNotNull(source, "source"); 2372 2373 double sum = 0; 2374 long count = 0; 2375 2376 foreach (var num in source) 2377 checked 2378 { 2379 sum += (double) num; 2380 count++; 2381 } 2382 2383 if (count == 0) 2384 throw new InvalidOperationException(); 2385 2386 return (double) sum/count; 2387 } 2388 2389 /// <summary> 2390 /// Computes the average of a sequence of nullable <see cref="System.Double" /> values 2391 /// that are obtained by invoking a transform function on each 2392 /// element of the input sequence. 2393 /// </summary> 2394 Average( this IEnumerable<TSource> source, Func<TSource, double> selector)2395 public static double Average<TSource>( 2396 this IEnumerable<TSource> source, 2397 Func<TSource, double> selector) 2398 { 2399 return source.Select(selector).Average(); 2400 } 2401 2402 2403 /// <summary> 2404 /// Computes the sum of a sequence of <see cref="System.Double" /> values. 2405 /// </summary> 2406 Sum( this IEnumerable<double?> source)2407 public static double? Sum( 2408 this IEnumerable<double?> source) 2409 { 2410 CheckNotNull(source, "source"); 2411 2412 double sum = 0; 2413 foreach (var num in source) 2414 sum = checked(sum + (num ?? 0)); 2415 2416 return sum; 2417 } 2418 2419 /// <summary> 2420 /// Computes the sum of a sequence of <see cref="System.Double" /> 2421 /// values that are obtained by invoking a transform function on 2422 /// each element of the input sequence. 2423 /// </summary> 2424 Sum( this IEnumerable<TSource> source, Func<TSource, double?> selector)2425 public static double? Sum<TSource>( 2426 this IEnumerable<TSource> source, 2427 Func<TSource, double?> selector) 2428 { 2429 return source.Select(selector).Sum(); 2430 } 2431 2432 /// <summary> 2433 /// Computes the average of a sequence of <see cref="System.Double" /> values. 2434 /// </summary> 2435 Average( this IEnumerable<double?> source)2436 public static double? Average( 2437 this IEnumerable<double?> source) 2438 { 2439 CheckNotNull(source, "source"); 2440 2441 double sum = 0; 2442 long count = 0; 2443 2444 foreach (var num in source.Where(n => n != null)) 2445 checked 2446 { 2447 sum += (double) num; 2448 count++; 2449 } 2450 2451 if (count == 0) 2452 return null; 2453 2454 return (double?) sum/count; 2455 } 2456 2457 /// <summary> 2458 /// Computes the average of a sequence of <see cref="System.Double" /> values 2459 /// that are obtained by invoking a transform function on each 2460 /// element of the input sequence. 2461 /// </summary> 2462 Average( this IEnumerable<TSource> source, Func<TSource, double?> selector)2463 public static double? Average<TSource>( 2464 this IEnumerable<TSource> source, 2465 Func<TSource, double?> selector) 2466 { 2467 return source.Select(selector).Average(); 2468 } 2469 2470 /// <summary> 2471 /// Returns the minimum value in a sequence of nullable 2472 /// <see cref="System.Double" /> values. 2473 /// </summary> 2474 Min( this IEnumerable<double?> source)2475 public static double? Min( 2476 this IEnumerable<double?> source) 2477 { 2478 CheckNotNull(source, "source"); 2479 2480 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); 2481 } 2482 2483 /// <summary> 2484 /// Invokes a transform function on each element of a sequence and 2485 /// returns the minimum nullable <see cref="System.Double" /> value. 2486 /// </summary> 2487 Min( this IEnumerable<TSource> source, Func<TSource, double?> selector)2488 public static double? Min<TSource>( 2489 this IEnumerable<TSource> source, 2490 Func<TSource, double?> selector) 2491 { 2492 return source.Select(selector).Min(); 2493 } 2494 2495 /// <summary> 2496 /// Returns the maximum value in a sequence of nullable 2497 /// <see cref="System.Double" /> values. 2498 /// </summary> 2499 Max( this IEnumerable<double?> source)2500 public static double? Max( 2501 this IEnumerable<double?> source) 2502 { 2503 CheckNotNull(source, "source"); 2504 2505 return MinMaxImpl(source.Where(x => x != null), 2506 null, (max, x) => x == null || (max != null && x.Value < max.Value)); 2507 } 2508 2509 /// <summary> 2510 /// Invokes a transform function on each element of a sequence and 2511 /// returns the maximum nullable <see cref="System.Double" /> value. 2512 /// </summary> 2513 Max( this IEnumerable<TSource> source, Func<TSource, double?> selector)2514 public static double? Max<TSource>( 2515 this IEnumerable<TSource> source, 2516 Func<TSource, double?> selector) 2517 { 2518 return source.Select(selector).Max(); 2519 } 2520 2521 /// <summary> 2522 /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values. 2523 /// </summary> 2524 Sum( this IEnumerable<decimal> source)2525 public static decimal Sum( 2526 this IEnumerable<decimal> source) 2527 { 2528 CheckNotNull(source, "source"); 2529 2530 decimal sum = 0; 2531 foreach (var num in source) 2532 sum = checked(sum + num); 2533 2534 return sum; 2535 } 2536 2537 /// <summary> 2538 /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> 2539 /// values that are obtained by invoking a transform function on 2540 /// each element of the input sequence. 2541 /// </summary> 2542 Sum( this IEnumerable<TSource> source, Func<TSource, decimal> selector)2543 public static decimal Sum<TSource>( 2544 this IEnumerable<TSource> source, 2545 Func<TSource, decimal> selector) 2546 { 2547 return source.Select(selector).Sum(); 2548 } 2549 2550 /// <summary> 2551 /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values. 2552 /// </summary> 2553 Average( this IEnumerable<decimal> source)2554 public static decimal Average( 2555 this IEnumerable<decimal> source) 2556 { 2557 CheckNotNull(source, "source"); 2558 2559 decimal sum = 0; 2560 long count = 0; 2561 2562 foreach (var num in source) 2563 checked 2564 { 2565 sum += (decimal) num; 2566 count++; 2567 } 2568 2569 if (count == 0) 2570 throw new InvalidOperationException(); 2571 2572 return (decimal) sum/count; 2573 } 2574 2575 /// <summary> 2576 /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values 2577 /// that are obtained by invoking a transform function on each 2578 /// element of the input sequence. 2579 /// </summary> 2580 Average( this IEnumerable<TSource> source, Func<TSource, decimal> selector)2581 public static decimal Average<TSource>( 2582 this IEnumerable<TSource> source, 2583 Func<TSource, decimal> selector) 2584 { 2585 return source.Select(selector).Average(); 2586 } 2587 2588 2589 /// <summary> 2590 /// Computes the sum of a sequence of <see cref="System.Decimal" /> values. 2591 /// </summary> 2592 Sum( this IEnumerable<decimal?> source)2593 public static decimal? Sum( 2594 this IEnumerable<decimal?> source) 2595 { 2596 CheckNotNull(source, "source"); 2597 2598 decimal sum = 0; 2599 foreach (var num in source) 2600 sum = checked(sum + (num ?? 0)); 2601 2602 return sum; 2603 } 2604 2605 /// <summary> 2606 /// Computes the sum of a sequence of <see cref="System.Decimal" /> 2607 /// values that are obtained by invoking a transform function on 2608 /// each element of the input sequence. 2609 /// </summary> 2610 Sum( this IEnumerable<TSource> source, Func<TSource, decimal?> selector)2611 public static decimal? Sum<TSource>( 2612 this IEnumerable<TSource> source, 2613 Func<TSource, decimal?> selector) 2614 { 2615 return source.Select(selector).Sum(); 2616 } 2617 2618 /// <summary> 2619 /// Computes the average of a sequence of <see cref="System.Decimal" /> values. 2620 /// </summary> 2621 Average( this IEnumerable<decimal?> source)2622 public static decimal? Average( 2623 this IEnumerable<decimal?> source) 2624 { 2625 CheckNotNull(source, "source"); 2626 2627 decimal sum = 0; 2628 long count = 0; 2629 2630 foreach (var num in source.Where(n => n != null)) 2631 checked 2632 { 2633 sum += (decimal) num; 2634 count++; 2635 } 2636 2637 if (count == 0) 2638 return null; 2639 2640 return (decimal?) sum/count; 2641 } 2642 2643 /// <summary> 2644 /// Computes the average of a sequence of <see cref="System.Decimal" /> values 2645 /// that are obtained by invoking a transform function on each 2646 /// element of the input sequence. 2647 /// </summary> 2648 Average( this IEnumerable<TSource> source, Func<TSource, decimal?> selector)2649 public static decimal? Average<TSource>( 2650 this IEnumerable<TSource> source, 2651 Func<TSource, decimal?> selector) 2652 { 2653 return source.Select(selector).Average(); 2654 } 2655 2656 /// <summary> 2657 /// Returns the minimum value in a sequence of nullable 2658 /// <see cref="System.Decimal" /> values. 2659 /// </summary> 2660 Min( this IEnumerable<decimal?> source)2661 public static decimal? Min( 2662 this IEnumerable<decimal?> source) 2663 { 2664 CheckNotNull(source, "source"); 2665 2666 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); 2667 } 2668 2669 /// <summary> 2670 /// Invokes a transform function on each element of a sequence and 2671 /// returns the minimum nullable <see cref="System.Decimal" /> value. 2672 /// </summary> 2673 Min( this IEnumerable<TSource> source, Func<TSource, decimal?> selector)2674 public static decimal? Min<TSource>( 2675 this IEnumerable<TSource> source, 2676 Func<TSource, decimal?> selector) 2677 { 2678 return source.Select(selector).Min(); 2679 } 2680 2681 /// <summary> 2682 /// Returns the maximum value in a sequence of nullable 2683 /// <see cref="System.Decimal" /> values. 2684 /// </summary> 2685 Max( this IEnumerable<decimal?> source)2686 public static decimal? Max( 2687 this IEnumerable<decimal?> source) 2688 { 2689 CheckNotNull(source, "source"); 2690 2691 return MinMaxImpl(source.Where(x => x != null), 2692 null, (max, x) => x == null || (max != null && x.Value < max.Value)); 2693 } 2694 2695 /// <summary> 2696 /// Invokes a transform function on each element of a sequence and 2697 /// returns the maximum nullable <see cref="System.Decimal" /> value. 2698 /// </summary> 2699 Max( this IEnumerable<TSource> source, Func<TSource, decimal?> selector)2700 public static decimal? Max<TSource>( 2701 this IEnumerable<TSource> source, 2702 Func<TSource, decimal?> selector) 2703 { 2704 return source.Select(selector).Max(); 2705 } 2706 } 2707 2708 /// <summary> 2709 /// Represents a collection of objects that have a common key. 2710 /// </summary> 2711 internal partial interface IGrouping<TKey, TElement> : IEnumerable<TElement> 2712 { 2713 /// <summary> 2714 /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />. 2715 /// </summary> 2716 2717 TKey Key { get; } 2718 } 2719 2720 /// <summary> 2721 /// Defines an indexer, size property, and Boolean search method for 2722 /// data structures that map keys to <see cref="IEnumerable{T}"/> 2723 /// sequences of values. 2724 /// </summary> 2725 internal partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>> 2726 { Contains(TKey key)2727 bool Contains(TKey key); 2728 int Count { get; } 2729 IEnumerable<TElement> this[TKey key] { get; } 2730 } 2731 2732 /// <summary> 2733 /// Represents a sorted sequence. 2734 /// </summary> 2735 internal partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement> 2736 { 2737 /// <summary> 2738 /// Performs a subsequent ordering on the elements of an 2739 /// <see cref="IOrderedEnumerable{T}"/> according to a key. 2740 /// </summary> 2741 CreateOrderedEnumerable( Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending)2742 IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>( 2743 Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending); 2744 } 2745 2746 /// <summary> 2747 /// Represents a collection of keys each mapped to one or more values. 2748 /// </summary> 2749 internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement> 2750 { 2751 private readonly Dictionary<TKey, IGrouping<TKey, TElement>> _map; 2752 Lookup(IEqualityComparer<TKey> comparer)2753 internal Lookup(IEqualityComparer<TKey> comparer) 2754 { 2755 _map = new Dictionary<TKey, IGrouping<TKey, TElement>>(comparer); 2756 } 2757 Add(IGrouping<TKey, TElement> item)2758 internal void Add(IGrouping<TKey, TElement> item) 2759 { 2760 _map.Add(item.Key, item); 2761 } 2762 Find(TKey key)2763 internal IEnumerable<TElement> Find(TKey key) 2764 { 2765 IGrouping<TKey, TElement> grouping; 2766 return _map.TryGetValue(key, out grouping) ? grouping : null; 2767 } 2768 2769 /// <summary> 2770 /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />. 2771 /// </summary> 2772 2773 public int Count 2774 { 2775 get { return _map.Count; } 2776 } 2777 2778 /// <summary> 2779 /// Gets the collection of values indexed by the specified key. 2780 /// </summary> 2781 2782 public IEnumerable<TElement> this[TKey key] 2783 { 2784 get 2785 { 2786 IGrouping<TKey, TElement> result; 2787 return _map.TryGetValue(key, out result) ? result : Enumerable.Empty<TElement>(); 2788 } 2789 } 2790 2791 /// <summary> 2792 /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />. 2793 /// </summary> 2794 Contains(TKey key)2795 public bool Contains(TKey key) 2796 { 2797 return _map.ContainsKey(key); 2798 } 2799 2800 /// <summary> 2801 /// Applies a transform function to each key and its associated 2802 /// values and returns the results. 2803 /// </summary> 2804 ApplyResultSelector( Func<TKey, IEnumerable<TElement>, TResult> resultSelector)2805 public IEnumerable<TResult> ApplyResultSelector<TResult>( 2806 Func<TKey, IEnumerable<TElement>, TResult> resultSelector) 2807 { 2808 if (resultSelector == null) 2809 throw new ArgumentNullException("resultSelector"); 2810 2811 foreach (var pair in _map) 2812 yield return resultSelector(pair.Key, pair.Value); 2813 } 2814 2815 /// <summary> 2816 /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />. 2817 /// </summary> 2818 GetEnumerator()2819 public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() 2820 { 2821 return _map.Values.GetEnumerator(); 2822 } 2823 IEnumerable.GetEnumerator()2824 IEnumerator IEnumerable.GetEnumerator() 2825 { 2826 return GetEnumerator(); 2827 } 2828 } 2829 2830 internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T> 2831 { 2832 private readonly IEnumerable<T> _source; 2833 private readonly List<Comparison<T>> _comparisons; 2834 OrderedEnumerable(IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> comparer, bool descending)2835 public OrderedEnumerable(IEnumerable<T> source, 2836 Func<T, K> keySelector, IComparer<K> comparer, bool descending) : 2837 this(source, null, keySelector, comparer, descending) 2838 { 2839 } 2840 OrderedEnumerable(IEnumerable<T> source, List<Comparison<T>> comparisons, Func<T, K> keySelector, IComparer<K> comparer, bool descending)2841 private OrderedEnumerable(IEnumerable<T> source, List<Comparison<T>> comparisons, 2842 Func<T, K> keySelector, IComparer<K> comparer, bool descending) 2843 { 2844 if (source == null) throw new ArgumentNullException("source"); 2845 if (keySelector == null) throw new ArgumentNullException("keySelector"); 2846 2847 _source = source; 2848 2849 comparer = comparer ?? Comparer<K>.Default; 2850 2851 if (comparisons == null) 2852 comparisons = new List<Comparison<T>>( /* capacity */ 4); 2853 2854 comparisons.Add((x, y) 2855 => (descending ? -1 : 1)*comparer.Compare(keySelector(x), keySelector(y))); 2856 2857 _comparisons = comparisons; 2858 } 2859 CreateOrderedEnumerable( Func<T, KK> keySelector, IComparer<KK> comparer, bool descending)2860 public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>( 2861 Func<T, KK> keySelector, IComparer<KK> comparer, bool descending) 2862 { 2863 return new OrderedEnumerable<T, KK>(_source, _comparisons, keySelector, comparer, descending); 2864 } 2865 GetEnumerator()2866 public IEnumerator<T> GetEnumerator() 2867 { 2868 // 2869 // We sort using List<T>.Sort, but docs say that it performs an 2870 // unstable sort. LINQ, on the other hand, says OrderBy performs 2871 // a stable sort. So convert the source sequence into a sequence 2872 // of tuples where the second element tags the position of the 2873 // element from the source sequence (First). The position is 2874 // then used as a tie breaker when all keys compare equal, 2875 // thus making the sort stable. 2876 // 2877 2878 var list = _source.Select(new Func<T, int, Tuple<T, int>>(TagPosition)).ToList(); 2879 2880 list.Sort((x, y) => 2881 { 2882 // 2883 // Compare keys from left to right. 2884 // 2885 2886 var comparisons = _comparisons; 2887 for (var i = 0; i < comparisons.Count; i++) 2888 { 2889 var result = comparisons[i](x.First, y.First); 2890 if (result != 0) 2891 return result; 2892 } 2893 2894 // 2895 // All keys compared equal so now break the tie by their 2896 // position in the original sequence, making the sort stable. 2897 // 2898 2899 return x.Second.CompareTo(y.Second); 2900 }); 2901 2902 return list.Select(new Func<Tuple<T, int>, T>(GetFirst)).GetEnumerator(); 2903 2904 } 2905 2906 /// <remarks> 2907 /// See <a href="http://code.google.com/p/linqbridge/issues/detail?id=11">issue #11</a> 2908 /// for why this method is needed and cannot be expressed as a 2909 /// lambda at the call site. 2910 /// </remarks> 2911 TagPosition(T e, int i)2912 private static Tuple<T, int> TagPosition(T e, int i) 2913 { 2914 return new Tuple<T, int>(e, i); 2915 } 2916 2917 /// <remarks> 2918 /// See <a href="http://code.google.com/p/linqbridge/issues/detail?id=11">issue #11</a> 2919 /// for why this method is needed and cannot be expressed as a 2920 /// lambda at the call site. 2921 /// </remarks> 2922 GetFirst(Tuple<T, int> pv)2923 private static T GetFirst(Tuple<T, int> pv) 2924 { 2925 return pv.First; 2926 } 2927 IEnumerable.GetEnumerator()2928 IEnumerator IEnumerable.GetEnumerator() 2929 { 2930 return GetEnumerator(); 2931 } 2932 } 2933 2934 [Serializable] 2935 internal struct Tuple<TFirst, TSecond> : IEquatable<Tuple<TFirst, TSecond>> 2936 { 2937 public TFirst First { get; private set; } 2938 public TSecond Second { get; private set; } 2939 TupleNewtonsoft.Json.Utilities.LinqBridge.Tuple2940 public Tuple(TFirst first, TSecond second) 2941 : this() 2942 { 2943 First = first; 2944 Second = second; 2945 } 2946 EqualsNewtonsoft.Json.Utilities.LinqBridge.Tuple2947 public override bool Equals(object obj) 2948 { 2949 return obj != null 2950 && obj is Tuple<TFirst, TSecond> 2951 && base.Equals((Tuple<TFirst, TSecond>) obj); 2952 } 2953 EqualsNewtonsoft.Json.Utilities.LinqBridge.Tuple2954 public bool Equals(Tuple<TFirst, TSecond> other) 2955 { 2956 return EqualityComparer<TFirst>.Default.Equals(other.First, First) 2957 && EqualityComparer<TSecond>.Default.Equals(other.Second, Second); 2958 } 2959 GetHashCodeNewtonsoft.Json.Utilities.LinqBridge.Tuple2960 public override int GetHashCode() 2961 { 2962 var num = 0x7a2f0b42; 2963 num = (-1521134295*num) + EqualityComparer<TFirst>.Default.GetHashCode(First); 2964 return (-1521134295*num) + EqualityComparer<TSecond>.Default.GetHashCode(Second); 2965 } 2966 ToStringNewtonsoft.Json.Utilities.LinqBridge.Tuple2967 public override string ToString() 2968 { 2969 return string.Format(@"{{ First = {0}, Second = {1} }}", First, Second); 2970 } 2971 } 2972 } 2973 2974 namespace Newtonsoft.Json.Serialization 2975 { Func()2976 public delegate TResult Func<TResult>(); 2977 Func(T a)2978 public delegate TResult Func<T, TResult>(T a); 2979 Func(T1 arg1, T2 arg2)2980 public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2); 2981 Func(T1 arg1, T2 arg2, T3 arg3)2982 public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3); 2983 Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4)2984 public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 2985 Action()2986 public delegate void Action(); 2987 Action(T1 arg1, T2 arg2)2988 public delegate void Action<T1, T2>(T1 arg1, T2 arg2); 2989 Action(T1 arg1, T2 arg2, T3 arg3)2990 public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3); 2991 Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4)2992 public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4); 2993 } 2994 2995 namespace System.Runtime.CompilerServices 2996 { 2997 /// <remarks> 2998 /// This attribute allows us to define extension methods without 2999 /// requiring .NET Framework 3.5. For more information, see the section, 3000 /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>, 3001 /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a> 3002 /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>, 3003 /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>. 3004 /// </remarks> 3005 3006 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] 3007 internal sealed class ExtensionAttribute : Attribute { } 3008 } 3009 3010 #endif