一直没好好地学习一下LINQ,只会平时常用的一几个。
师傅这几天问到,就顺便整理了一下。
以下是几个平时未用到的。
public static ILookup<TKey, TSource> ToLookup<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector )
与GroupBy功能差不多,都会创建类字典集合,区别在于:
GroupBy是延迟加载,所以即使使用GroupBy得到结果集合,若原操作目标集合发生改变,那结果集合的元素也会发生相应的改变。
创建一个ILookup集合,此集合不像Dictionary,其元素是不可改变的。
非延迟执行。
public sealed class Product { public int Id { get; set; } public string Category { get; set; } public double Value { get; set; } public override string ToString() { return string.Format("[{0}: {1} - {2}]", Id, Category, Value); } } public static void Test() { var products = new List<Product> { new Product {Id = 1, Category = "Electronics", Value = 15.0}, new Product {Id = 2, Category = "Groceries", Value = 40.0}, new Product {Id = 3, Category = "Garden", Value = 210.3}, new Product {Id = 4, Category = "Pets", Value = 2.1}, new Product {Id = 5, Category = "Electronics", Value = 19.95}, new Product {Id = 6, Category = "Pets", Value = 21.25}, new Product {Id = 7, Category = "Pets", Value = 5.50}, new Product {Id = 8, Category = "Garden", Value = 13.0}, new Product {Id = 9, Category = "Automotive", Value = 10.0}, new Product {Id = 10, Category = "Electronics", Value = 250.0}, }; //若使用GroupBy,则所有Garden产品最后不会被打印出来 //若使用ToLookup,则所有Garden产品最后还是会被打印出来 var groups = products.ToLookup(pr => pr.Category); //删除所有属于Garden的产品 products.RemoveAll(pr => pr.Category == "Garden"); //打印结果 foreach (var group in groups) { Console.WriteLine(group.Key); foreach (var item in group) { Console.WriteLine("\t" + item); } } }
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>( this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector )
合并两个序列。
结果序列的元素个数为两个序列中的元素个数较少的。
延迟执行。
int[] numbers = { 1, 2, 3, 4 }; string[] words = { "one", "two", "three" }; var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second); foreach (var item in numbersAndWords) Console.WriteLine(item); // This code produces the following output: // 1 one // 2 two // 3 three
public static IEnumerable<TResult> Repeat<TResult>( TResult element, int count )
生成包含一个重复值的序列
注意非扩展方法。
延迟执行。
IEnumerable<string> strings = Enumerable.Repeat("I like programming.", 15); foreach (String str in strings) { Console.WriteLine(str); } /* This code produces the following output: I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. I like programming. */
public static IEnumerable<int> Range( int start, int count )
生成指定范围内的整数的序列。
延迟执行。
IEnumerable<int> squares = Enumerable.Range(1, 5); foreach (var num in squares) { Console.WriteLine(num); } /* This code produces the following output: 1 2 3 4 5 */
public static IEnumerable<TResult> OfType<TResult>( this IEnumerable source )
根据指定类型筛选 IEnumerable 的元素。
延迟执行。
System.Collections.ArrayList fruits = new System.Collections.ArrayList(4); fruits.Add("Mango"); fruits.Add("Orange"); fruits.Add("Apple"); fruits.Add(3.0); fruits.Add(4.0); fruits.Add(5); fruits.Add("6.0"); // Apply OfType() to the ArrayList. IEnumerable<double > query1 = fruits.OfType<double>(); Console.WriteLine("Elements of type 'double' are:"); foreach (var element in query1) { Console.WriteLine(element); } // This code produces the following output: // // Elements of type 'double' are: // 3 // 4
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector )
延迟执行。
用法与SQL中的JOIN用法相似,参考以下的SQL:
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors a LEFT OUTER JOIN publishers p
ON a.city = p.city
class Person { public string Name { get; set; } } class Pet { public string Name { get; set; } public Person Owner { get; set; } } public static void JoinEx1() { Person magnus = new Person { Name = "Hedlund, Magnus" }; Person terry = new Person { Name = "Adams, Terry" }; Person charlotte = new Person { Name = "Weiss, Charlotte" }; Pet barley = new Pet { Name = "Barley", Owner = terry }; Pet boots = new Pet { Name = "Boots", Owner = terry }; Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte }; Pet daisy = new Pet { Name = "Daisy", Owner = magnus }; List<Person> people = new List<Person> { magnus, terry, charlotte }; List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy }; // Create a list of Person-Pet pairs where // each element is an anonymous type that contains a // Pet's name and the name of the Person that owns the Pet. var query = people.Join(pets, person => person, pet => pet.Owner, (person, pet) => new { OwnerName = person.Name, Pet = pet.Name }); foreach (var obj in query) { Console.WriteLine( "{0} - {1}", obj.OwnerName, obj.Pet); } } /* This code produces the following output: Hedlund, Magnus - Daisy Adams, Terry - Barley Adams, Terry - Boots Weiss, Charlotte - Whiskers */