1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100 |
- #region License, Terms and Author(s)
- //
- // LINQBridge
- // Copyright (c) 2007 Atif Aziz, Joseph Albahari. All rights reserved.
- //
- // Author(s):
- //
- // Atif Aziz, http://www.raboof.com
- //
- // This library is free software; you can redistribute it and/or modify it
- // under the terms of the New BSD License, a copy of which should have
- // been delivered along with this distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- //
- #endregion
- // $Id: Enumerable.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
- namespace System.Linq
- {
- #region Imports
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using LinqBridge;
- #endregion
- /// <summary>
- /// Provides a set of static (Shared in Visual Basic) methods for
- /// querying objects that implement <see cref="IEnumerable{T}" />.
- /// </summary>
- static partial class Enumerable
- {
- /// <summary>
- /// Returns the input typed as <see cref="IEnumerable{T}"/>.
- /// </summary>
- public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
- {
- return source;
- }
- /// <summary>
- /// Returns an empty <see cref="IEnumerable{T}"/> that has the
- /// specified type argument.
- /// </summary>
- public static IEnumerable<TResult> Empty<TResult>()
- {
- return Sequence<TResult>.Empty;
- }
- /// <summary>
- /// Converts the elements of an <see cref="IEnumerable"/> to the
- /// specified type.
- /// </summary>
- public static IEnumerable<TResult> Cast<TResult>(
- this IEnumerable source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return CastYield<TResult>(source);
- }
- private static IEnumerable<TResult> CastYield<TResult>(
- IEnumerable source)
- {
- foreach (var item in source)
- yield return (TResult)item;
- }
- /// <summary>
- /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type.
- /// </summary>
- public static IEnumerable<TResult> OfType<TResult>(
- this IEnumerable source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return OfTypeYield<TResult>(source);
- }
- private static IEnumerable<TResult> OfTypeYield<TResult>(
- IEnumerable source)
- {
- foreach (var item in source)
- if (item is TResult)
- yield return (TResult)item;
- }
- /// <summary>
- /// Generates a sequence of integral numbers within a specified range.
- /// </summary>
- /// <param name="start">The value of the first integer in the sequence.</param>
- /// <param name="count">The number of sequential integers to generate.</param>
- public static IEnumerable<int> Range(int start, int count)
- {
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", count, null);
- var end = (long)start + count;
- if (end - 1 >= int.MaxValue)
- throw new ArgumentOutOfRangeException("count", count, null);
- return RangeYield(start, end);
- }
- private static IEnumerable<int> RangeYield(int start, long end)
- {
- for (var i = start; i < end; i++)
- yield return i;
- }
- /// <summary>
- /// Generates a sequence that contains one repeated value.
- /// </summary>
- public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
- {
- if (count < 0) throw new ArgumentOutOfRangeException("count", count, null);
- return RepeatYield(element, count);
- }
- private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count)
- {
- for (var i = 0; i < count; i++)
- yield return element;
- }
- /// <summary>
- /// Filters a sequence of values based on a predicate.
- /// </summary>
- public static IEnumerable<TSource> Where<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- if (predicate == null) throw new ArgumentNullException("predicate");
- return source.Where((item, i) => predicate(item));
- }
- /// <summary>
- /// Filters a sequence of values based on a predicate.
- /// Each element's index is used in the logic of the predicate function.
- /// </summary>
- public static IEnumerable<TSource> Where<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (predicate == null) throw new ArgumentNullException("predicate");
- return WhereYield(source, predicate);
- }
- private static IEnumerable<TSource> WhereYield<TSource>(
- IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- var i = 0;
- foreach (var item in source)
- if (predicate(item, i++))
- yield return item;
- }
- /// <summary>
- /// Projects each element of a sequence into a new form.
- /// </summary>
- public static IEnumerable<TResult> Select<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TResult> selector)
- {
- if (selector == null) throw new ArgumentNullException("selector");
- return source.Select((item, i) => selector(item));
- }
- /// <summary>
- /// Projects each element of a sequence into a new form by
- /// incorporating the element's index.
- /// </summary>
- public static IEnumerable<TResult> Select<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, TResult> selector)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (selector == null) throw new ArgumentNullException("selector");
- return SelectYield(source, selector);
- }
- private static IEnumerable<TResult> SelectYield<TSource, TResult>(
- IEnumerable<TSource> source,
- FFunc<TSource, int, TResult> selector)
- {
- var i = 0;
- foreach (var item in source)
- yield return selector(item, i++);
- }
- /// <summary>
- /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />
- /// and flattens the resulting sequences into one sequence.
- /// </summary>
- public static IEnumerable<TResult> SelectMany<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, IEnumerable<TResult>> selector)
- {
- if (selector == null) throw new ArgumentNullException("selector");
- return source.SelectMany((item, i) => selector(item));
- }
- /// <summary>
- /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
- /// and flattens the resulting sequences into one sequence. The
- /// index of each source element is used in the projected form of
- /// that element.
- /// </summary>
- public static IEnumerable<TResult> SelectMany<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, IEnumerable<TResult>> selector)
- {
- if (selector == null) throw new ArgumentNullException("selector");
- return source.SelectMany(selector, (item, subitem) => subitem);
- }
- /// <summary>
- /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
- /// flattens the resulting sequences into one sequence, and invokes
- /// a result selector function on each element therein.
- /// </summary>
- public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, IEnumerable<TCollection>> collectionSelector,
- FFunc<TSource, TCollection, TResult> resultSelector)
- {
- if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
- return source.SelectMany((item, i) => collectionSelector(item), resultSelector);
- }
- /// <summary>
- /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
- /// flattens the resulting sequences into one sequence, and invokes
- /// a result selector function on each element therein. The index of
- /// each source element is used in the intermediate projected form
- /// of that element.
- /// </summary>
- public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, IEnumerable<TCollection>> collectionSelector,
- FFunc<TSource, TCollection, TResult> resultSelector)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- return SelectManyYield(source, collectionSelector, resultSelector);
- }
- private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, IEnumerable<TCollection>> collectionSelector,
- FFunc<TSource, TCollection, TResult> resultSelector)
- {
- var i = 0;
- foreach (var item in source)
- foreach (var subitem in collectionSelector(item, i++))
- yield return resultSelector(item, subitem);
- }
- /// <summary>
- /// Returns elements from a sequence as long as a specified condition is true.
- /// </summary>
- public static IEnumerable<TSource> TakeWhile<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- if (predicate == null) throw new ArgumentNullException("predicate");
- return source.TakeWhile((item, i) => predicate(item));
- }
- /// <summary>
- /// Returns elements from a sequence as long as a specified condition is true.
- /// The element's index is used in the logic of the predicate function.
- /// </summary>
- public static IEnumerable<TSource> TakeWhile<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (predicate == null) throw new ArgumentNullException("predicate");
- return TakeWhileYield(source, predicate);
- }
- private static IEnumerable<TSource> TakeWhileYield<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- var i = 0;
- foreach (var item in source)
- if (predicate(item, i++))
- yield return item;
- else
- break;
- }
- /// <summary>
- /// Returns a specified number of contiguous elements from the start
- /// of a sequence.
- /// </summary>
- public static IEnumerable<TSource> Take<TSource>(
- this IEnumerable<TSource> source,
- int count)
- {
- return source.TakeWhile((item, i) => i < count);
- }
- private static class Futures<T>
- {
- public static readonly FFunc<T> Default = () => default(T);
- public static readonly FFunc<T> Undefined = () => { throw new InvalidOperationException(); };
- }
- /// <summary>
- /// Base implementation of First operator.
- /// </summary>
- private static TSource FirstImpl<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource> empty)
- {
- if (source == null) throw new ArgumentNullException("source");
- Debug.Assert(empty != null);
- var list = source as IList<TSource>; // optimized case for lists
- if (list != null)
- return list.Count > 0 ? list[0] : empty();
- using (var e = source.GetEnumerator()) // fallback for enumeration
- return e.MoveNext() ? e.Current : empty();
- }
- /// <summary>
- /// Returns the first element of a sequence.
- /// </summary>
- public static TSource First<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.FirstImpl(Futures<TSource>.Undefined);
- }
- /// <summary>
- /// Returns the first element in a sequence that satisfies a specified condition.
- /// </summary>
- public static TSource First<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return First(source.Where(predicate));
- }
- /// <summary>
- /// Returns the first element of a sequence, or a default value if
- /// the sequence contains no elements.
- /// </summary>
- public static TSource FirstOrDefault<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.FirstImpl(Futures<TSource>.Default);
- }
- /// <summary>
- /// Returns the first element of the sequence that satisfies a
- /// condition or a default value if no such element is found.
- /// </summary>
- public static TSource FirstOrDefault<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return FirstOrDefault(source.Where(predicate));
- }
- /// <summary>
- /// Base implementation of Last operator.
- /// </summary>
- private static TSource LastImpl<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource> empty)
- {
- if (source == null) throw new ArgumentNullException("source");
- var list = source as IList<TSource>; // optimized case for lists
- if (list != null)
- return list.Count > 0 ? list[list.Count - 1] : empty();
- using (var e = source.GetEnumerator())
- {
- if (!e.MoveNext())
- return empty();
- var last = e.Current;
- while (e.MoveNext())
- last = e.Current;
- return last;
- }
- }
- /// <summary>
- /// Returns the last element of a sequence.
- /// </summary>
- public static TSource Last<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.LastImpl(Futures<TSource>.Undefined);
- }
- /// <summary>
- /// Returns the last element of a sequence that satisfies a
- /// specified condition.
- /// </summary>
- public static TSource Last<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return Last(source.Where(predicate));
- }
- /// <summary>
- /// Returns the last element of a sequence, or a default value if
- /// the sequence contains no elements.
- /// </summary>
- public static TSource LastOrDefault<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.LastImpl(Futures<TSource>.Default);
- }
- /// <summary>
- /// Returns the last element of a sequence that satisfies a
- /// condition or a default value if no such element is found.
- /// </summary>
- public static TSource LastOrDefault<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return LastOrDefault(source.Where(predicate));
- }
- /// <summary>
- /// Base implementation of Single operator.
- /// </summary>
- private static TSource SingleImpl<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource> empty)
- {
- if (source == null) throw new ArgumentNullException("source");
- using (var e = source.GetEnumerator())
- {
- if (e.MoveNext())
- {
- var single = e.Current;
- if (!e.MoveNext())
- return single;
- throw new InvalidOperationException();
- }
- return empty();
- }
- }
- /// <summary>
- /// Returns the only element of a sequence, and throws an exception
- /// if there is not exactly one element in the sequence.
- /// </summary>
- public static TSource Single<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.SingleImpl(Futures<TSource>.Undefined);
- }
- /// <summary>
- /// Returns the only element of a sequence that satisfies a
- /// specified condition, and throws an exception if more than one
- /// such element exists.
- /// </summary>
- public static TSource Single<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return Single(source.Where(predicate));
- }
- /// <summary>
- /// Returns the only element of a sequence, or a default value if
- /// the sequence is empty; this method throws an exception if there
- /// is more than one element in the sequence.
- /// </summary>
- public static TSource SingleOrDefault<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.SingleImpl(Futures<TSource>.Default);
- }
- /// <summary>
- /// Returns the only element of a sequence that satisfies a
- /// specified condition or a default value if no such element
- /// exists; this method throws an exception if more than one element
- /// satisfies the condition.
- /// </summary>
- public static TSource SingleOrDefault<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return SingleOrDefault(source.Where(predicate));
- }
- /// <summary>
- /// Returns the element at a specified index in a sequence.
- /// </summary>
- public static TSource ElementAt<TSource>(
- this IEnumerable<TSource> source,
- int index)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (index < 0)
- throw new ArgumentOutOfRangeException("index", index, null);
- var list = source as IList<TSource>;
- if (list != null)
- return list[index];
- try
- {
- return source.SkipWhile((item, i) => i < index).First();
- }
- catch (InvalidOperationException) // if thrown by First
- {
- throw new ArgumentOutOfRangeException("index", index, null);
- }
- }
- /// <summary>
- /// Returns the element at a specified index in a sequence or a
- /// default value if the index is out of range.
- /// </summary>
- public static TSource ElementAtOrDefault<TSource>(
- this IEnumerable<TSource> source,
- int index)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (index < 0)
- return default(TSource);
- var list = source as IList<TSource>;
- if (list != null)
- return index < list.Count ? list[index] : default(TSource);
- return source.SkipWhile((item, i) => i < index).FirstOrDefault();
- }
- /// <summary>
- /// Inverts the order of the elements in a sequence.
- /// </summary>
- public static IEnumerable<TSource> Reverse<TSource>(
- this IEnumerable<TSource> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return ReverseYield(source);
- }
- private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source)
- {
- var stack = new Stack<TSource>();
- foreach (var item in source)
- stack.Push(item);
- foreach (var item in stack)
- yield return item;
- }
- /// <summary>
- /// Bypasses elements in a sequence as long as a specified condition
- /// is true and then returns the remaining elements.
- /// </summary>
- public static IEnumerable<TSource> SkipWhile<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- if (predicate == null) throw new ArgumentNullException("predicate");
- return source.SkipWhile((item, i) => predicate(item));
- }
- /// <summary>
- /// Bypasses elements in a sequence as long as a specified condition
- /// is true and then returns the remaining elements. The element's
- /// index is used in the logic of the predicate function.
- /// </summary>
- public static IEnumerable<TSource> SkipWhile<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (predicate == null) throw new ArgumentNullException("predicate");
- return SkipWhileYield(source, predicate);
- }
- private static IEnumerable<TSource> SkipWhileYield<TSource>(
- IEnumerable<TSource> source,
- FFunc<TSource, int, bool> predicate)
- {
- using (var e = source.GetEnumerator())
- {
- for (var i = 0; ; i++)
- {
- if (!e.MoveNext())
- yield break;
- if (!predicate(e.Current, i))
- break;
- }
- do { yield return e.Current; } while (e.MoveNext());
- }
- }
- /// <summary>
- /// Bypasses a specified number of elements in a sequence and then
- /// returns the remaining elements.
- /// </summary>
- public static IEnumerable<TSource> Skip<TSource>(
- this IEnumerable<TSource> source,
- int count)
- {
- return source.SkipWhile((item, i) => i < count);
- }
- /// <summary>
- /// Returns the number of elements in a sequence.
- /// </summary>
- public static int Count<TSource>(
- this IEnumerable<TSource> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- var collection = source as ICollection;
- return collection != null
- ? collection.Count
- : source.Aggregate(0, (count, item) => checked(count + 1));
- }
- /// <summary>
- /// Returns a number that represents how many elements in the
- /// specified sequence satisfy a condition.
- /// </summary>
- public static int Count<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return Count(source.Where(predicate));
- }
- /// <summary>
- /// Returns an <see cref="Int64"/> that represents the total number
- /// of elements in a sequence.
- /// </summary>
- public static long LongCount<TSource>(
- this IEnumerable<TSource> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- var array = source as Array;
- return array != null
- ? array.LongLength
- : source.Aggregate(0L, (count, item) => count + 1);
- }
- /// <summary>
- /// Returns an <see cref="Int64"/> that represents how many elements
- /// in a sequence satisfy a condition.
- /// </summary>
- public static long LongCount<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return LongCount(source.Where(predicate));
- }
- /// <summary>
- /// Concatenates two sequences.
- /// </summary>
- public static IEnumerable<TSource> Concat<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- if (first == null) throw new ArgumentNullException("first");
- if (second == null) throw new ArgumentNullException("second");
- return ConcatYield(first, second);
- }
- private static IEnumerable<TSource> ConcatYield<TSource>(
- IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- foreach (var item in first)
- yield return item;
- foreach (var item in second)
- yield return item;
- }
- /// <summary>
- /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>.
- /// </summary>
- public static List<TSource> ToList<TSource>(
- this IEnumerable<TSource> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return new List<TSource>(source);
- }
- /// <summary>
- /// Creates an array from an <see cref="IEnumerable{T}"/>.
- /// </summary>
- public static TSource[] ToArray<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.ToList().ToArray();
- }
- /// <summary>
- /// Returns distinct elements from a sequence by using the default
- /// equality comparer to compare values.
- /// </summary>
- public static IEnumerable<TSource> Distinct<TSource>(
- this IEnumerable<TSource> source)
- {
- return Distinct(source, /* comparer */ null);
- }
- /// <summary>
- /// Returns distinct elements from a sequence by using a specified
- /// <see cref="IEqualityComparer{T}"/> to compare values.
- /// </summary>
- public static IEnumerable<TSource> Distinct<TSource>(
- this IEnumerable<TSource> source,
- IEqualityComparer<TSource> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- return DistinctYield(source, comparer);
- }
- private static IEnumerable<TSource> DistinctYield<TSource>(
- IEnumerable<TSource> source,
- IEqualityComparer<TSource> comparer)
- {
- var set = new Dictionary<TSource, object>(comparer);
- var gotNull = false;
- foreach (var item in source)
- {
- if (item == null)
- {
- if (gotNull)
- continue;
- gotNull = true;
- }
- else
- {
- if (set.ContainsKey(item))
- continue;
- set.Add(item, null);
- }
- yield return item;
- }
- }
- /// <summary>
- /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function.
- /// </summary>
- public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return ToLookup(source, keySelector, e => e, /* comparer */ null);
- }
- /// <summary>
- /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function and a key comparer.
- /// </summary>
- public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IEqualityComparer<TKey> comparer)
- {
- return ToLookup(source, keySelector, e => e, comparer);
- }
- /// <summary>
- /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
- /// <see cref="IEnumerable{T}" /> according to specified key
- /// and element selector functions.
- /// </summary>
- public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector)
- {
- return ToLookup(source, keySelector, elementSelector, /* comparer */ null);
- }
- /// <summary>
- /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function, a comparer and an element selector function.
- /// </summary>
- public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- if (elementSelector == null) throw new ArgumentNullException("elementSelector");
- var lookup = new Lookup<TKey, TElement>(comparer);
- foreach (var item in source)
- {
- var key = keySelector(item);
- var grouping = (Grouping<TKey, TElement>)lookup.Find(key);
- if (grouping == null)
- {
- grouping = new Grouping<TKey, TElement>(key);
- lookup.Add(grouping);
- }
- grouping.Add(elementSelector(item));
- }
- return lookup;
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function.
- /// </summary>
- public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return GroupBy(source, keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and compares the keys by using a specified
- /// comparer.
- /// </summary>
- public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IEqualityComparer<TKey> comparer)
- {
- return GroupBy(source, keySelector, e => e, comparer);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and projects the elements for each group by
- /// using a specified function.
- /// </summary>
- public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector)
- {
- return GroupBy(source, keySelector, elementSelector, /* comparer */ null);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and creates a result value from each group and
- /// its key.
- /// </summary>
- public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- if (elementSelector == null) throw new ArgumentNullException("elementSelector");
- return ToLookup(source, keySelector, elementSelector, comparer);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a key selector
- /// function. The keys are compared by using a comparer and each
- /// group's elements are projected by using a specified function.
- /// </summary>
- public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TKey, IEnumerable<TSource>, TResult> resultSelector)
- {
- return GroupBy(source, keySelector, resultSelector, /* comparer */ null);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and creates a result value from each group and
- /// its key. The elements of each group are projected by using a
- /// specified function.
- /// </summary>
- public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TKey, IEnumerable<TSource>, TResult> resultSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g));
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and creates a result value from each group and
- /// its key. The keys are compared by using a specified comparer.
- /// </summary>
- public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector,
- FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector)
- {
- return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null);
- }
- /// <summary>
- /// Groups the elements of a sequence according to a specified key
- /// selector function and creates a result value from each group and
- /// its key. Key values are compared by using a specified comparer,
- /// and the elements of each group are projected by using a
- /// specified function.
- /// </summary>
- public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector,
- FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- if (elementSelector == null) throw new ArgumentNullException("elementSelector");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- return ToLookup(source, keySelector, elementSelector, comparer)
- .Select(g => resultSelector(g.Key, g));
- }
- /// <summary>
- /// Applies an accumulator function over a sequence.
- /// </summary>
- public static TSource Aggregate<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TSource, TSource> func)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (func == null) throw new ArgumentNullException("func");
- using (var e = source.GetEnumerator())
- {
- if (!e.MoveNext())
- throw new InvalidOperationException();
- return e.Renumerable().Skip(1).Aggregate(e.Current, func);
- }
- }
- /// <summary>
- /// Applies an accumulator function over a sequence. The specified
- /// seed value is used as the initial accumulator value.
- /// </summary>
- public static TAccumulate Aggregate<TSource, TAccumulate>(
- this IEnumerable<TSource> source,
- TAccumulate seed,
- FFunc<TAccumulate, TSource, TAccumulate> func)
- {
- return Aggregate(source, seed, func, r => r);
- }
- /// <summary>
- /// Applies an accumulator function over a sequence. The specified
- /// seed value is used as the initial accumulator value, and the
- /// specified function is used to select the result value.
- /// </summary>
- public static TResult Aggregate<TSource, TAccumulate, TResult>(
- this IEnumerable<TSource> source,
- TAccumulate seed,
- FFunc<TAccumulate, TSource, TAccumulate> func,
- FFunc<TAccumulate, TResult> resultSelector)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (func == null) throw new ArgumentNullException("func");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- var result = seed;
- foreach (var item in source)
- result = func(result, item);
- return resultSelector(result);
- }
- /// <summary>
- /// Produces the set union of two sequences by using the default
- /// equality comparer.
- /// </summary>
- public static IEnumerable<TSource> Union<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- return Union(first, second, /* comparer */ null);
- }
- /// <summary>
- /// Produces the set union of two sequences by using a specified
- /// <see cref="IEqualityComparer{T}" />.
- /// </summary>
- public static IEnumerable<TSource> Union<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second,
- IEqualityComparer<TSource> comparer)
- {
- return first.Concat(second).Distinct(comparer);
- }
- /// <summary>
- /// Returns the elements of the specified sequence or the type
- /// parameter's default value in a singleton collection if the
- /// sequence is empty.
- /// </summary>
- public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
- this IEnumerable<TSource> source)
- {
- return source.DefaultIfEmpty(default(TSource));
- }
- /// <summary>
- /// Returns the elements of the specified sequence or the specified
- /// value in a singleton collection if the sequence is empty.
- /// </summary>
- public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
- this IEnumerable<TSource> source,
- TSource defaultValue)
- {
- if (source == null) throw new ArgumentNullException("source");
- return DefaultIfEmptyYield(source, defaultValue);
- }
- private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>(
- IEnumerable<TSource> source,
- TSource defaultValue)
- {
- using (var e = source.GetEnumerator())
- {
- if (!e.MoveNext())
- yield return defaultValue;
- else
- do { yield return e.Current; } while (e.MoveNext());
- }
- }
- /// <summary>
- /// Determines whether all elements of a sequence satisfy a condition.
- /// </summary>
- public static bool All<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (predicate == null) throw new ArgumentNullException("predicate");
- foreach (var item in source)
- if (!predicate(item))
- return false;
- return true;
- }
- /// <summary>
- /// Determines whether a sequence contains any elements.
- /// </summary>
- public static bool Any<TSource>(
- this IEnumerable<TSource> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- using (var e = source.GetEnumerator())
- return e.MoveNext();
- }
- /// <summary>
- /// Determines whether any element of a sequence satisfies a
- /// condition.
- /// </summary>
- public static bool Any<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, bool> predicate)
- {
- return source.Where(predicate).Any();
- }
- /// <summary>
- /// Determines whether a sequence contains a specified element by
- /// using the default equality comparer.
- /// </summary>
- public static bool Contains<TSource>(
- this IEnumerable<TSource> source,
- TSource value)
- {
- return source.Contains(value, /* comparer */ null);
- }
- /// <summary>
- /// Determines whether a sequence contains a specified element by
- /// using a specified <see cref="IEqualityComparer{T}" />.
- /// </summary>
- public static bool Contains<TSource>(
- this IEnumerable<TSource> source,
- TSource value,
- IEqualityComparer<TSource> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (comparer == null)
- {
- var collection = source as ICollection<TSource>;
- if (collection != null)
- return collection.Contains(value);
- }
- comparer = comparer ?? EqualityComparer<TSource>.Default;
- return source.Any(item => comparer.Equals(item, value));
- }
- /// <summary>
- /// Determines whether two sequences are equal by comparing the
- /// elements by using the default equality comparer for their type.
- /// </summary>
- public static bool SequenceEqual<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- return first.SequenceEqual(second, /* comparer */ null);
- }
- /// <summary>
- /// Determines whether two sequences are equal by comparing their
- /// elements by using a specified <see cref="IEqualityComparer{T}" />.
- /// </summary>
- public static bool SequenceEqual<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second,
- IEqualityComparer<TSource> comparer)
- {
- if (first == null) throw new ArgumentNullException("frist");
- if (second == null) throw new ArgumentNullException("second");
- comparer = comparer ?? EqualityComparer<TSource>.Default;
- using (IEnumerator<TSource> lhs = first.GetEnumerator(),
- rhs = second.GetEnumerator())
- {
- do
- {
- if (!lhs.MoveNext())
- return !rhs.MoveNext();
- if (!rhs.MoveNext())
- return false;
- }
- while (comparer.Equals(lhs.Current, rhs.Current));
- }
- return false;
- }
- /// <summary>
- /// Base implementation for Min/Max operator.
- /// </summary>
- private static TSource MinMaxImpl<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TSource, bool> lesser)
- {
- if (source == null) throw new ArgumentNullException("source");
- Debug.Assert(lesser != null);
- if (typeof(TSource).IsClass) // ReSharper disable CompareNonConstrainedGenericWithNull
- source = source.Where(e => e != null).DefaultIfEmpty(); // ReSharper restore CompareNonConstrainedGenericWithNull
- return source.Aggregate((a, item) => lesser(a, item) ? a : item);
- }
- /// <summary>
- /// Base implementation for Min/Max operator for nullable types.
- /// </summary>
- private static TSource? MinMaxImpl<TSource>(
- this IEnumerable<TSource?> source,
- TSource? seed, FFunc<TSource?, TSource?, bool> lesser) where TSource : struct
- {
- if (source == null) throw new ArgumentNullException("source");
- Debug.Assert(lesser != null);
- return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item);
- // == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser);
- }
- /// <summary>
- /// Returns the minimum value in a generic sequence.
- /// </summary>
- public static TSource Min<TSource>(
- this IEnumerable<TSource> source)
- {
- var comparer = Comparer<TSource>.Default;
- return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0);
- }
- /// <summary>
- /// Invokes a transform function on each element of a generic
- /// sequence and returns the minimum resulting value.
- /// </summary>
- public static TResult Min<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TResult> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a generic sequence.
- /// </summary>
- public static TSource Max<TSource>(
- this IEnumerable<TSource> source)
- {
- var comparer = Comparer<TSource>.Default;
- return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0);
- }
- /// <summary>
- /// Invokes a transform function on each element of a generic
- /// sequence and returns the maximum resulting value.
- /// </summary>
- public static TResult Max<TSource, TResult>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TResult> selector)
- {
- return source.Select(selector).Max();
- }
- /// <summary>
- /// Makes an enumerator seen as enumerable once more.
- /// </summary>
- /// <remarks>
- /// The supplied enumerator must have been started. The first element
- /// returned is the element the enumerator was on when passed in.
- /// DO NOT use this method if the caller must be a generator. It is
- /// mostly safe among aggregate operations.
- /// </remarks>
- private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e)
- {
- Debug.Assert(e != null);
- do { yield return e.Current; } while (e.MoveNext());
- }
- /// <summary>
- /// Sorts the elements of a sequence in ascending order according to a key.
- /// </summary>
- public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return source.OrderBy(keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Sorts the elements of a sequence in ascending order by using a
- /// specified comparer.
- /// </summary>
- public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false);
- }
- /// <summary>
- /// Sorts the elements of a sequence in descending order according to a key.
- /// </summary>
- public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return source.OrderByDescending(keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Sorts the elements of a sequence in descending order by using a
- /// specified comparer.
- /// </summary>
- public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (source == null) throw new ArgumentNullException("keySelector");
- return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true);
- }
- /// <summary>
- /// Performs a subsequent ordering of the elements in a sequence in
- /// ascending order according to a key.
- /// </summary>
- public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
- this IOrderedEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return source.ThenBy(keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Performs a subsequent ordering of the elements in a sequence in
- /// ascending order by using a specified comparer.
- /// </summary>
- public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
- this IOrderedEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false);
- }
- /// <summary>
- /// Performs a subsequent ordering of the elements in a sequence in
- /// descending order, according to a key.
- /// </summary>
- public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
- this IOrderedEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return source.ThenByDescending(keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Performs a subsequent ordering of the elements in a sequence in
- /// descending order by using a specified comparer.
- /// </summary>
- public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
- this IOrderedEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true);
- }
- /// <summary>
- /// Base implementation for Intersect and Except operators.
- /// </summary>
- private static IEnumerable<TSource> IntersectExceptImpl<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second,
- IEqualityComparer<TSource> comparer,
- bool flag)
- {
- if (first == null) throw new ArgumentNullException("first");
- if (second == null) throw new ArgumentNullException("second");
- var keys = new List<Key<TSource>>();
- var flags = new Dictionary<Key<TSource>, bool>(new KeyComparer<TSource>(comparer));
- foreach (var item in from item in first
- select new Key<TSource>(item) into item
- where !flags.ContainsKey(item)
- select item)
- {
- flags.Add(item, !flag);
- keys.Add(item);
- }
- foreach (var item in from item in second
- select new Key<TSource>(item) into item
- where flags.ContainsKey(item)
- select item)
- {
- flags[item] = flag;
- }
- //
- // As per docs, "the marked elements are yielded in the order in
- // which they were collected.
- //
- return from item in keys where flags[item] select item.Value;
- }
- /// <summary>
- /// Produces the set intersection of two sequences by using the
- /// default equality comparer to compare values.
- /// </summary>
- public static IEnumerable<TSource> Intersect<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- return first.Intersect(second, /* comparer */ null);
- }
- /// <summary>
- /// Produces the set intersection of two sequences by using the
- /// specified <see cref="IEqualityComparer{T}" /> to compare values.
- /// </summary>
- public static IEnumerable<TSource> Intersect<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second,
- IEqualityComparer<TSource> comparer)
- {
- return IntersectExceptImpl(first, second, comparer, /* flag */ true);
- }
- /// <summary>
- /// Produces the set difference of two sequences by using the
- /// default equality comparer to compare values.
- /// </summary>
- public static IEnumerable<TSource> Except<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second)
- {
- return first.Except(second, /* comparer */ null);
- }
- /// <summary>
- /// Produces the set difference of two sequences by using the
- /// specified <see cref="IEqualityComparer{T}" /> to compare values.
- /// </summary>
- public static IEnumerable<TSource> Except<TSource>(
- this IEnumerable<TSource> first,
- IEnumerable<TSource> second,
- IEqualityComparer<TSource> comparer)
- {
- return IntersectExceptImpl(first, second, comparer, /* flag */ false);
- }
- /// <summary>
- /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function.
- /// </summary>
- public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector)
- {
- return source.ToDictionary(keySelector, /* comparer */ null);
- }
- /// <summary>
- /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function and key comparer.
- /// </summary>
- public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- IEqualityComparer<TKey> comparer)
- {
- return source.ToDictionary(keySelector, e => e, comparer);
- }
- /// <summary>
- /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
- /// <see cref="IEnumerable{T}" /> according to specified key
- /// selector and element selector functions.
- /// </summary>
- public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector)
- {
- return source.ToDictionary(keySelector, elementSelector, /* comparer */ null);
- }
- /// <summary>
- /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
- /// <see cref="IEnumerable{T}" /> according to a specified key
- /// selector function, a comparer, and an element selector function.
- /// </summary>
- public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
- this IEnumerable<TSource> source,
- FFunc<TSource, TKey> keySelector,
- FFunc<TSource, TElement> elementSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- if (elementSelector == null) throw new ArgumentNullException("elementSelector");
- var dict = new Dictionary<TKey, TElement>(comparer);
- foreach (var item in source)
- {
- //
- // ToDictionary is meant to throw ArgumentNullException if
- // keySelector produces a key that is null and
- // Argument exception if keySelector produces duplicate keys
- // for two elements. Incidentally, the doucmentation for
- // IDictionary<TKey, TValue>.Add says that the Add method
- // throws the same exceptions under the same circumstances
- // so we don't need to do any additional checking or work
- // here and let the Add implementation do all the heavy
- // lifting.
- //
- dict.Add(keySelector(item), elementSelector(item));
- }
- return dict;
- }
- /// <summary>
- /// Correlates the elements of two sequences based on matching keys.
- /// The default equality comparer is used to compare keys.
- /// </summary>
- public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
- this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner,
- FFunc<TOuter, TKey> outerKeySelector,
- FFunc<TInner, TKey> innerKeySelector,
- FFunc<TOuter, TInner, TResult> resultSelector)
- {
- return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
- }
- /// <summary>
- /// Correlates the elements of two sequences based on matching keys.
- /// The default equality comparer is used to compare keys. A
- /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys.
- /// </summary>
- public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
- this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner,
- FFunc<TOuter, TKey> outerKeySelector,
- FFunc<TInner, TKey> innerKeySelector,
- FFunc<TOuter, TInner, TResult> resultSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (outer == null) throw new ArgumentNullException("outer");
- if (inner == null) throw new ArgumentNullException("inner");
- if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
- if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- var lookup = inner.ToLookup(innerKeySelector, comparer);
- return
- from o in outer
- from i in lookup[outerKeySelector(o)]
- select resultSelector(o, i);
- }
- /// <summary>
- /// Correlates the elements of two sequences based on equality of
- /// keys and groups the results. The default equality comparer is
- /// used to compare keys.
- /// </summary>
- public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
- this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner,
- FFunc<TOuter, TKey> outerKeySelector,
- FFunc<TInner, TKey> innerKeySelector,
- FFunc<TOuter, IEnumerable<TInner>, TResult> resultSelector)
- {
- return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
- }
- /// <summary>
- /// Correlates the elements of two sequences based on equality of
- /// keys and groups the results. The default equality comparer is
- /// used to compare keys. A specified <see cref="IEqualityComparer{T}" />
- /// is used to compare keys.
- /// </summary>
- public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
- this IEnumerable<TOuter> outer,
- IEnumerable<TInner> inner,
- FFunc<TOuter, TKey> outerKeySelector,
- FFunc<TInner, TKey> innerKeySelector,
- FFunc<TOuter, IEnumerable<TInner>, TResult> resultSelector,
- IEqualityComparer<TKey> comparer)
- {
- if (outer == null) throw new ArgumentNullException("outer");
- if (inner == null) throw new ArgumentNullException("inner");
- if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
- if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
- if (resultSelector == null) throw new ArgumentNullException("resultSelector");
- var lookup = inner.ToLookup(innerKeySelector, comparer);
- return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)]));
- }
- private static class Sequence<T>
- {
- public static readonly IEnumerable<T> Empty = new T[0];
- }
- private sealed class Grouping<K, V> : List<V>, IGrouping<K, V>
- {
- internal Grouping(K key)
- {
- Key = key;
- }
- public K Key { get; private set; }
- }
- }
- }
- // $Id: Enumerable.g.tt 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System.Linq
- {
- #region Imports
- using System;
- using System.Collections.Generic;
- #endregion
- // This partial implementation was template-generated:
- // Mon, 16 Apr 2012 20:05:53 GMT
- partial class Enumerable
- {
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values.
- /// </summary>
- public static int Sum(
- this IEnumerable<int> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- int sum = 0;
- foreach (var num in source)
- sum = checked(sum + num);
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Int32" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static int Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values.
- /// </summary>
- public static double Average(
- this IEnumerable<int> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- long count = 0;
- foreach (var num in source)
- checked
- {
- sum += (int)num;
- count++;
- }
- if (count == 0)
- throw new InvalidOperationException();
- return (double)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Int32" /> values.
- /// </summary>
- public static int? Sum(
- this IEnumerable<int?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- int sum = 0;
- foreach (var num in source)
- sum = checked(sum + (num ?? 0));
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Int32" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static int? Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int?> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Int32" /> values.
- /// </summary>
- public static double? Average(
- this IEnumerable<int?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- long count = 0;
- foreach (var num in source.Where(n => n != null))
- checked
- {
- sum += (int)num;
- count++;
- }
- if (count == 0)
- return null;
- return (double?)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Int32" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double? Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int?> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Returns the minimum value in a sequence of nullable
- /// <see cref="System.Int32" /> values.
- /// </summary>
- public static int? Min(
- this IEnumerable<int?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the minimum nullable <see cref="System.Int32" /> value.
- /// </summary>
- public static int? Min<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int?> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a sequence of nullable
- /// <see cref="System.Int32" /> values.
- /// </summary>
- public static int? Max(
- this IEnumerable<int?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null),
- null, (max, x) => x == null || (max != null && x.Value < max.Value));
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the maximum nullable <see cref="System.Int32" /> value.
- /// </summary>
- public static int? Max<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, int?> selector)
- {
- return source.Select(selector).Max();
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values.
- /// </summary>
- public static long Sum(
- this IEnumerable<long> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- foreach (var num in source)
- sum = checked(sum + num);
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Int64" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static long Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values.
- /// </summary>
- public static double Average(
- this IEnumerable<long> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- long count = 0;
- foreach (var num in source)
- checked
- {
- sum += (long)num;
- count++;
- }
- if (count == 0)
- throw new InvalidOperationException();
- return (double)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Int64" /> values.
- /// </summary>
- public static long? Sum(
- this IEnumerable<long?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- foreach (var num in source)
- sum = checked(sum + (num ?? 0));
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Int64" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static long? Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long?> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Int64" /> values.
- /// </summary>
- public static double? Average(
- this IEnumerable<long?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- long sum = 0;
- long count = 0;
- foreach (var num in source.Where(n => n != null))
- checked
- {
- sum += (long)num;
- count++;
- }
- if (count == 0)
- return null;
- return (double?)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Int64" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double? Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long?> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Returns the minimum value in a sequence of nullable
- /// <see cref="System.Int64" /> values.
- /// </summary>
- public static long? Min(
- this IEnumerable<long?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the minimum nullable <see cref="System.Int64" /> value.
- /// </summary>
- public static long? Min<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long?> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a sequence of nullable
- /// <see cref="System.Int64" /> values.
- /// </summary>
- public static long? Max(
- this IEnumerable<long?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null),
- null, (max, x) => x == null || (max != null && x.Value < max.Value));
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the maximum nullable <see cref="System.Int64" /> value.
- /// </summary>
- public static long? Max<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, long?> selector)
- {
- return source.Select(selector).Max();
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values.
- /// </summary>
- public static float Sum(
- this IEnumerable<float> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- float sum = 0;
- foreach (var num in source)
- sum = checked(sum + num);
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Single" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static float Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Single" /> values.
- /// </summary>
- public static float Average(
- this IEnumerable<float> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- float sum = 0;
- long count = 0;
- foreach (var num in source)
- checked
- {
- sum += (float)num;
- count++;
- }
- if (count == 0)
- throw new InvalidOperationException();
- return (float)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Single" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static float Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Single" /> values.
- /// </summary>
- public static float? Sum(
- this IEnumerable<float?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- float sum = 0;
- foreach (var num in source)
- sum = checked(sum + (num ?? 0));
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Single" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static float? Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float?> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Single" /> values.
- /// </summary>
- public static float? Average(
- this IEnumerable<float?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- float sum = 0;
- long count = 0;
- foreach (var num in source.Where(n => n != null))
- checked
- {
- sum += (float)num;
- count++;
- }
- if (count == 0)
- return null;
- return (float?)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Single" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static float? Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float?> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Returns the minimum value in a sequence of nullable
- /// <see cref="System.Single" /> values.
- /// </summary>
- public static float? Min(
- this IEnumerable<float?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the minimum nullable <see cref="System.Single" /> value.
- /// </summary>
- public static float? Min<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float?> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a sequence of nullable
- /// <see cref="System.Single" /> values.
- /// </summary>
- public static float? Max(
- this IEnumerable<float?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null),
- null, (max, x) => x == null || (max != null && x.Value < max.Value));
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the maximum nullable <see cref="System.Single" /> value.
- /// </summary>
- public static float? Max<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, float?> selector)
- {
- return source.Select(selector).Max();
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values.
- /// </summary>
- public static double Sum(
- this IEnumerable<double> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- double sum = 0;
- foreach (var num in source)
- sum = checked(sum + num);
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Double" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static double Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Double" /> values.
- /// </summary>
- public static double Average(
- this IEnumerable<double> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- double sum = 0;
- long count = 0;
- foreach (var num in source)
- checked
- {
- sum += (double)num;
- count++;
- }
- if (count == 0)
- throw new InvalidOperationException();
- return (double)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Double" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Double" /> values.
- /// </summary>
- public static double? Sum(
- this IEnumerable<double?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- double sum = 0;
- foreach (var num in source)
- sum = checked(sum + (num ?? 0));
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Double" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static double? Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double?> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Double" /> values.
- /// </summary>
- public static double? Average(
- this IEnumerable<double?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- double sum = 0;
- long count = 0;
- foreach (var num in source.Where(n => n != null))
- checked
- {
- sum += (double)num;
- count++;
- }
- if (count == 0)
- return null;
- return (double?)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Double" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static double? Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double?> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Returns the minimum value in a sequence of nullable
- /// <see cref="System.Double" /> values.
- /// </summary>
- public static double? Min(
- this IEnumerable<double?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the minimum nullable <see cref="System.Double" /> value.
- /// </summary>
- public static double? Min<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double?> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a sequence of nullable
- /// <see cref="System.Double" /> values.
- /// </summary>
- public static double? Max(
- this IEnumerable<double?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null),
- null, (max, x) => x == null || (max != null && x.Value < max.Value));
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the maximum nullable <see cref="System.Double" /> value.
- /// </summary>
- public static double? Max<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, double?> selector)
- {
- return source.Select(selector).Max();
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal Sum(
- this IEnumerable<decimal> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- decimal sum = 0;
- foreach (var num in source)
- sum = checked(sum + num);
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of nullable <see cref="System.Decimal" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static decimal Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal Average(
- this IEnumerable<decimal> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- decimal sum = 0;
- long count = 0;
- foreach (var num in source)
- checked
- {
- sum += (decimal)num;
- count++;
- }
- if (count == 0)
- throw new InvalidOperationException();
- return (decimal)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static decimal Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal? Sum(
- this IEnumerable<decimal?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- decimal sum = 0;
- foreach (var num in source)
- sum = checked(sum + (num ?? 0));
- return sum;
- }
- /// <summary>
- /// Computes the sum of a sequence of <see cref="System.Decimal" />
- /// values that are obtained by invoking a transform function on
- /// each element of the input sequence.
- /// </summary>
- public static decimal? Sum<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal?> selector)
- {
- return source.Select(selector).Sum();
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal? Average(
- this IEnumerable<decimal?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- decimal sum = 0;
- long count = 0;
- foreach (var num in source.Where(n => n != null))
- checked
- {
- sum += (decimal)num;
- count++;
- }
- if (count == 0)
- return null;
- return (decimal?)sum / count;
- }
- /// <summary>
- /// Computes the average of a sequence of <see cref="System.Decimal" /> values
- /// that are obtained by invoking a transform function on each
- /// element of the input sequence.
- /// </summary>
- public static decimal? Average<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal?> selector)
- {
- return source.Select(selector).Average();
- }
- /// <summary>
- /// Returns the minimum value in a sequence of nullable
- /// <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal? Min(
- this IEnumerable<decimal?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the minimum nullable <see cref="System.Decimal" /> value.
- /// </summary>
- public static decimal? Min<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal?> selector)
- {
- return source.Select(selector).Min();
- }
- /// <summary>
- /// Returns the maximum value in a sequence of nullable
- /// <see cref="System.Decimal" /> values.
- /// </summary>
- public static decimal? Max(
- this IEnumerable<decimal?> source)
- {
- if (source == null) throw new ArgumentNullException("source");
- return MinMaxImpl(source.Where(x => x != null),
- null, (max, x) => x == null || (max != null && x.Value < max.Value));
- }
- /// <summary>
- /// Invokes a transform function on each element of a sequence and
- /// returns the maximum nullable <see cref="System.Decimal" /> value.
- /// </summary>
- public static decimal? Max<TSource>(
- this IEnumerable<TSource> source,
- FFunc<TSource, decimal?> selector)
- {
- return source.Select(selector).Max();
- }
- }
- }
- // $Id: ExtensionAttribute.cs 898b3d493ed6 2012/04/17 20:09:57 azizatif $
- namespace System.Runtime.CompilerServices
- {
- /// <remarks>
- /// This attribute allows us to define extension methods without
- /// requiring .NET Framework 3.5. For more information, see the section,
- /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
- /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
- /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>,
- /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
- /// </remarks>
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
- public sealed partial class ExtensionAttribute : Attribute { }
- }
- // $Id: Func.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System
- {
- #if LINQBRIDGE_LIB
- public delegate TResult FFunc<out TResult>();
- public delegate TResult FFunc<in T, out TResult>(T a);
- public delegate TResult FFunc<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
- public delegate TResult FFunc<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
- public delegate TResult FFunc<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- #else
- public delegate TResult FFunc<TResult>();
- public delegate TResult FFunc<T, TResult>(T a);
- public delegate TResult FFunc<T1, T2, TResult>(T1 arg1, T2 arg2);
- public delegate TResult FFunc<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
- public delegate TResult FFunc<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- #endif
- }
- // $Id: IGrouping.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System.Linq
- {
- #region Imports
- using System.Collections.Generic;
- #endregion
- /// <summary>
- /// Represents a collection of objects that have a common key.
- /// </summary>
- partial interface IGrouping<out TKey, TElement> : IEnumerable<TElement>
- {
- /// <summary>
- /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />.
- /// </summary>
- TKey Key { get; }
- }
- }
- // $Id: ILookup.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System.Linq
- {
- using System.Collections.Generic;
- /// <summary>
- /// Defines an indexer, size property, and Boolean search method for
- /// data structures that map keys to <see cref="IEnumerable{T}"/>
- /// sequences of values.
- /// </summary>
- partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
- {
- bool Contains(TKey key);
- int Count { get; }
- IEnumerable<TElement> this[TKey key] { get; }
- }
- }
- // $Id: Internal.cs 1567e00f1a20 2012/04/17 16:09:51 azizatif $
- namespace LinqBridge
- {
- #region Imports
- using System;
- using System.Collections.Generic;
- #endregion
- /// <remarks>
- /// This type is not intended to be used directly from user code.
- /// It may be removed or changed in a future version without notice.
- /// </remarks>
- sealed class DelegatingComparer<T> : IComparer<T>
- {
- private readonly FFunc<T, T, int> _comparer;
- public DelegatingComparer(FFunc<T, T, int> comparer)
- {
- if (comparer == null) throw new ArgumentNullException("comparer");
- _comparer = comparer;
- }
- public int Compare(T x, T y) { return _comparer(x, y); }
- }
- /// <remarks>
- /// This type is not intended to be used directly from user code.
- /// It may be removed or changed in a future version without notice.
- /// </remarks>
- struct Key<T>
- {
- public Key(T value) : this() { Value = value; }
- public T Value { get; private set; }
- }
- /// <remarks>
- /// This type is not intended to be used directly from user code.
- /// It may be removed or changed in a future version without notice.
- /// </remarks>
- sealed class KeyComparer<T> : IEqualityComparer<Key<T>>
- {
- private readonly IEqualityComparer<T> _innerComparer;
- public KeyComparer(IEqualityComparer<T> innerComparer)
- {
- _innerComparer = innerComparer ?? EqualityComparer<T>.Default;
- }
- public bool Equals(Key<T> x, Key<T> y)
- {
- return _innerComparer.Equals(x.Value, y.Value);
- }
- public int GetHashCode(Key<T> obj)
- {
- return obj.Value == null ? 0 : _innerComparer.GetHashCode(obj.Value);
- }
- }
- }
- // $Id: IOrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System.Linq
- {
- using System.Collections.Generic;
- /// <summary>
- /// Represents a sorted sequence.
- /// </summary>
- partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
- {
- /// <summary>
- /// Performs a subsequent ordering on the elements of an
- /// <see cref="IOrderedEnumerable{T}"/> according to a key.
- /// </summary>
- IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(
- FFunc<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
- }
- }
- // $Id: Lookup.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
- namespace System.Linq
- {
- #region Imports
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using IEnumerable = System.Collections.IEnumerable;
- using LinqBridge;
- #endregion
- /// <summary>
- /// Represents a collection of keys each mapped to one or more values.
- /// </summary>
- internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
- {
- private readonly Dictionary<Key<TKey>, IGrouping<TKey, TElement>> _map;
- private readonly List<Key<TKey>> _orderedKeys; // remember order of insertion
- internal Lookup(IEqualityComparer<TKey> comparer)
- {
- _map = new Dictionary<Key<TKey>, IGrouping<TKey, TElement>>(new KeyComparer<TKey>(comparer));
- _orderedKeys = new List<Key<TKey>>();
- }
- internal void Add(IGrouping<TKey, TElement> item)
- {
- var key = new Key<TKey>(item.Key);
- _map.Add(key, item);
- _orderedKeys.Add(key);
- }
- internal IEnumerable<TElement> Find(TKey key)
- {
- IGrouping<TKey, TElement> grouping;
- return _map.TryGetValue(new Key<TKey>(key), out grouping) ? grouping : null;
- }
- /// <summary>
- /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />.
- /// </summary>
- public int Count
- {
- get { return _map.Count; }
- }
- /// <summary>
- /// Gets the collection of values indexed by the specified key.
- /// </summary>
- public IEnumerable<TElement> this[TKey key]
- {
- get
- {
- IGrouping<TKey, TElement> result;
- return _map.TryGetValue(new Key<TKey>(key), out result) ? result : Enumerable.Empty<TElement>();
- }
- }
- /// <summary>
- /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />.
- /// </summary>
- public bool Contains(TKey key)
- {
- return _map.ContainsKey(new Key<TKey>(key));
- }
- /// <summary>
- /// Applies a transform function to each key and its associated
- /// values and returns the results.
- /// </summary>
- public IEnumerable<TResult> ApplyResultSelector<TResult>(
- FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector)
- {
- if (resultSelector == null)
- throw new ArgumentNullException("resultSelector");
- foreach (var pair in _map)
- yield return resultSelector(pair.Key.Value, pair.Value);
- }
- /// <summary>
- /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />.
- /// </summary>
- public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
- {
- foreach (var key in _orderedKeys)
- yield return _map[key];
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- }
- // $Id: OrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace LinqBridge
- {
- #region Imports
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- #endregion
- internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T>
- {
- private readonly IEnumerable<T> _source;
- private readonly FFunc<T[], IComparer<int>, IComparer<int>> _comparerComposer;
- public OrderedEnumerable(IEnumerable<T> source,
- FFunc<T, K> keySelector, IComparer<K> comparer, bool descending) :
- this(source, (_, next) => next, keySelector, comparer, descending) { }
- private OrderedEnumerable(IEnumerable<T> source,
- FFunc<T[], IComparer<int>, IComparer<int>> parent,
- FFunc<T, K> keySelector, IComparer<K> comparer, bool descending)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- Debug.Assert(parent != null);
- _source = source;
- comparer = comparer ?? Comparer<K>.Default;
- var direction = descending ? -1 : 1;
- _comparerComposer = (items, next) =>
- {
- Debug.Assert(items != null);
- Debug.Assert(next != null);
- var keys = new K[items.Length];
- for (var i = 0; i < items.Length; i++)
- keys[i] = keySelector(items[i]);
- return parent(items, new DelegatingComparer<int>((i, j) =>
- {
- var result = direction * comparer.Compare(keys[i], keys[j]);
- return result != 0 ? result : next.Compare(i, j);
- }));
- };
- }
- public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>(
- FFunc<T, KK> keySelector, IComparer<KK> comparer, bool descending)
- {
- return new OrderedEnumerable<T, KK>(_source, _comparerComposer, keySelector, comparer, descending);
- }
- public IEnumerator<T> GetEnumerator()
- {
- //
- // Sort using Array.Sort but docs say that it performs an
- // unstable sort. LINQ, on the other hand, says OrderBy performs
- // a stable sort. Use the item position then as a tie
- // breaker when all keys compare equal, thus making the sort
- // stable.
- //
- var items = _source.ToArray();
- var positionComparer = new DelegatingComparer<int>((i, j) => i.CompareTo(j));
- var comparer = _comparerComposer(items, positionComparer);
- var keys = new int[items.Length];
- for (var i = 0; i < keys.Length; i++)
- keys[i] = i;
- Array.Sort(keys, items, comparer);
- return ((IEnumerable<T>)items).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- }
- // $Id: Action.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
- namespace System
- {
- #if LINQBRIDGE_LIB
- public delegate void Action();
- public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
- public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
- public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- #else
- public delegate void FsDbAction();
- public delegate void FsDbAction<T1, T2>(T1 arg1, T2 arg2);
- public delegate void FsDbAction<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
- public delegate void FsDbAction<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- #endif
- }
|