Ցուցակների հետ աշխատելն այն է, ինչ ծրագրավորող լինելն է: Լավ, ես ձգում եմ այն այստեղ, բայց դա այնքան էլ հեռու չէ ճշմարտությունից:
Եթե C#-ը մարդ լիներ, LINQ-ը կլիներ նրա պարանոցային երակը: Ցանկանում եմ ներկայացնել առկա մեթոդներից մի քանիսը, որոնք այնքան էլ հաճախ չեն օգտագործվում։ Առնվազն կրտսեր մշակողների կողմից: Վստահ չեմ, արդյոք դա պայմանավորված է նրանց մասին գիտելիքների պակասով, թե՞ նրանք լուծում են այնպիսի խնդիրներ, որոնք այնքան էլ հաճախ չեն լինում:
Հուսով ենք, որ այն կլինի կարճ և բովանդակալից ընթերցանություն:
OfType<T>()
Զտում է թիրախային տիպի տարրերը ցանկում: Ենթադրենք, որ դուք ունեք պոտենցիալ զրոյական օբյեկտների ցանկ, և ցանկանում եք զտել արժեք ունեցողները: Պարզության համար ես կօգտագործեմ ամբողջ թվեր.
List<int?> numbers = new() { 1, 2, null, 4, null }; var noNulls = numbers.OfType<int>(); // 1, 2, 4
Մեկ այլ պոտենցիալ օգտագործումը կլինի որոշակի դասի օբյեկտների զտումը.
class Animal { } class Dog : Animal { } class Cat : Animal { } List<Animal> animals = new() { new Cat(), new Cat(), new Cat(), new Dog(), new Dog() }; var dogs = animals.OfType<Dog>();
dogs
ցուցակը պետք է պարունակի 2 տարր այստեղ:
Aggregate()
Սա fold/reduce
-ի LINQ իրականացումն է: Ես այստեղ չեմ բացատրի, թե ինչ է անում fold ֆունկցիան: Եթե չգիտեք, դադարեք կարդալ այս հոդվածը և փնտրեք այն: Պարզ օգտագործում.
List<int> numbers = Enumerable .Range(0, 100) .ToList(); var sumFrom = 0; var total = numbers .Aggregate(sumFrom, (sum, x) => sum + x);
Նկատի ունեցեք, որ սա միայն ցուցադրական նպատակով է: Այս դեպքում դուք պետք է օգտագործեք Sum()
մեթոդը:
SelectMany()
Բազմաթիվ ցուցակները հարթեցնում է մեկ ցուցակի: Դիտարկենք մոդելը.
class Newspapers { string Name; List<Article> Articles; } class Article { string Title; List<Paragraph> Paragraphs; } class Paragraph { int WordCount; }
Ասեք, որ մենք ունենք տարբեր թերթերի ցանկ, և մենք ցանկանում ենք յուրաքանչյուր թերթի բոլոր հոդվածները հավաքել մեկ ցուցակի մեջ.
List<Newspapers> newspapers = new() { new Newspapers(), new Newspapers() }; IEnumerable<Article> articles = newspapers.SelectMany(x => x.Articles);
Մենք կարող ենք խորանալ այնքան, որքան ցանկանում ենք: Այսպիսով, մենք կարող ենք հեշտությամբ հարթեցնել թերթերի հոդվածները, քան ստանալ և հարթեցնել պարբերությունները յուրաքանչյուր հոդվածի համար, ինչպես այսպես.
IEnumerable<Paragraph> paragraphs = newspapers .SelectMany(np => np.Articles, (np, articles) => articles) .SelectMany(article => article.Paragraphs); var totalWordCount = paragraphs.Sum(x => x.WordCount);
Փորձեք դա անել՝ օգտագործելով սովորական Select()
, և դուք կհասկանաք այս մեթոդի օգտակարությունը:
Կրկին, հիշեք, որ սա միայն ներկայացման համար է: Դուք պետք է ծաղրեք տվյալները, որպեսզի դա աշխատի, քանի որ ներքին ցուցակները չեն ստեղծվում, և նման ամեն ինչ կանչելը բացառություն կստեղծի:
ToLookup()
Ստեղծում է որոնման աղյուսակ ցուցակից՝ հիմնվելով որպես բանալի տրամադրված հատկության վրա… Ավելի հեշտ է հասկանալ, երբ դուք պարզապես տեսնում եք այն: Դիտարկենք մոդելը.
class Character { public Character(string name, Category catg) { Name = name; Category = catg; } public string Name; public Category Category; } enum Category { Knight, Archer, Thief, Mage }
Եկեք ավելացնենք որոշ կեղծ տվյալներ աշխատելու համար և փոխարկենք դրանք փնտրման.
List<Character> characters = new() { new Character("Arthur", Category.Knight), new Character("Lancelot", Category.Knight), new Character("Legolas", Category.Archer), new Character("Robin Hood", Category.Archer), new Character("Garrett", Category.Thief), new Character("Gandalf", Category.Mage), new Character("Merlin", Category.Mage) }; ILookup<Category, Character> lookup = characters .ToLookup(x => x.Category);
Սա բաժանում է ցանկը՝ հիմնվելով մեր տրամադրած բանալի վրա՝ Category
: Պարզության համար ստուգենք որոնման աղյուսակի կառուցվածքը: Ես օգտագործում եմ LinqPad-ը՝ սա անելու համար.
Բավական կոկիկ: Այժմ մենք կարող ենք մուտք գործել որոշակի հավաքածու՝ հիմնվելով բանալիի վրա.
List<Character> knights = lookup[Category.Knight]; List<Character> archers = lookup[Category.Archer]; List<Character> thieves = lookup[Category.Thief]; List<Character> mages = lookup[Category.Mage];
Այնուամենայնիվ, կարևոր նշում. Մի օգտագործեք սա GroupBy()
-ի փոխարեն: Կիրառեք այն միայն այն բաների վրա, որոնք արդեն բեռնված են/թվարկված են: ToLookup()
-ի կատարումը չի հետաձգվում: Միշտ հիշիր դա:
Ահա և վերջ։ Եթե դուք C# noob եք, համոզվեք, որ ստուգեք ամբողջ գրադարանը: Դա կօգնի ձեզ ավելի մաքուր ծածկագիր գրել: Չնայած այս ֆունկցիոնալության մի մասի նմանակումը լավ է ցուցակների մանիպուլյացիայի ալգորիթմներ կիրառելու համար: Եթե դուք այլևս C# noob չեք, միգուցե այստեղ ինչ-որ բան կար, որի մասին ամբողջովին մոռացել եք: Ես գիտեմ, որ իմ նախկին աշխատանքում ինչ-որ ծածկագիր ունեմ, որը թողել եմ անփոփոխ…
Շնորհակալություն կարդալու համար :)