LINQ之延迟执行标准查询操作符(中)
2012-03-16 16:49
525 查看
操作符:Concat描述:用于连接2个序列原型:1种
public static IEnumerable<TSource> Concat<TSource>( this IEnumerable<TSource> first, IEnumerable<TSource> second )
string [] dogs = {"kelly","belly","shelly"}; string[] cats = {"kiti", "lili"}; var pets = dogs.Concat(cats); foreach (var pet in pets) { Console.WriteLine(pet); }返回的结果是:kellybellyshellykitilili操作符:OrderBy描述:允许输入序列根据一个keySelector方法进行升序排序,并返回一个排序后的结果:IOrderedEnumerable<TSource>原型:2种原型一:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector )在这种原型中,TKey必须是实现了IComparable<TKey>
string [] dogs = {"kelly","belly","shelly"};string[] cats = {"kiti", "lili"};var pets = dogs.Concat(cats).OrderBy(item=>item);foreach (var pet in pets){Console.WriteLine(pet);}需要注意的是,OrderBy后返回的是一个已经排序的结果:IOrderedEnumerable<TSource>,此时我们不应该在对这个序列调用OrderBy方法,因为这样会破坏原有的OrderBy的排序,如果我们需要再次针对其他的key进行排序,可以调用ThenBy,稍后会提到。原型二:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,Func<TSource, TKey> keySelector,IComparer<TKey> comparer)原型二和原型一很类似,只是多提供了一个IComparer的参数,允许我们传入自己的排序算法。这样子的话,TKey就不一定要是想IComparer接口了。我们还是来看个例子:我们有一个Student类:
public class Student{public string Name { get; set; }public List<int > Scores { get; set; }}我们希望根据Student的Scores的和来做一个降序排序,因此,我们另外建一个类来实现IComparer:
public class SortStudentScore:IComparer<Student>{public int Compare(Student x, Student y){decimal xScores = x.Scores.Sum(item => item);decimal yScores = y.Scores.Sum(item => item);return yScores.CompareTo(xScores);}}这样,我们的查询可以写成:
//定义数据源List<Student> students = new List<Student>{new Student{Name = "Terry",Scores = new List<int>{98,88,93,75,82}},new Student{Name = "Tina",Scores = new List<int>{85,99,87,93,97}},new Student{Name = "Linda",Scores = new List<int>{57,100,83,89,92}},new Student{Name = "Leon",Scores = new List<int>{100,98,72,77,84}},new Student{Name = "Echo",Scores = new List<int>{79,80,97,55,88}}};SortStudentScore sortStudentScore = new SortStudentScore();//定义查询表达式,找出不及格的学生及其分数var scoreQuery = students.OrderBy((s => s),sortStudentScore).Select(item=>new {item.Name,TotalScore= item.Scores.Sum(score=>score)});//输出结果)foreach (var query in scoreQuery){Console.WriteLine("Student:{0} TotalScore:{1}", query.Name, query.TotalScore);}我们的输出结果就是:Student:Tina TotalScore:461Student:Terry TotalScore:436Student:Leon TotalScore:431Student:Linda TotalScore:421Student:Echo TotalScore:399操作符:OrderByDescending描述:与OrderBy操作符类似,只是排序方式是按照降序来排序的。原型:与OrderBy一样,支持2种原型具体例子可以参照OrderBy的,不再赘述。操作符:ThenBy描述:将一个已经排序后的序列,根据新的key进行再排序。主要,与大多数LINQ操作不一样的地方是,ThenBy(以及后面要介绍的ThenByDescending)的输入序列都必须是实现了IOrderedEnumerable<T>。由于ThenBy是稳定排序,因此对于OrderBy/OrderByDescending后,ThenBy的key相同的2个元素,不会再打乱其排序。原型:2种,跟OrderBy一样为了说明这点,我们举个例子:
//定义数据源List<Student> students = new List<Student>{new Student{Id = 1,Name = "Leon",Scores = new List<int>{98,88,93,75,82}},new Student{Id = 2,Name = "Tina",Scores = new List<int>{85,99,87,93,97}},new Student{Id = 3,Name = "Linda",Scores = new List<int>{57,100,83,89,92}},new Student{Id = 4,Name = "Leon",Scores = new List<int>{100,98,77,77,84}},new Student{Id = 5,Name = "Echo",Scores = new List<int>{79,80,97,55,88}}};SortStudentScore sortStudentScore = new SortStudentScore();var orderByScoreQuery = students.OrderBy((s => s), sortStudentScore).Select(item => new {item.Id, item.Name, TotalScore = item.Scores.Sum(score => score) });Console.WriteLine("Using OrderBy only");//输出结果));foreach (var query in orderByScoreQuery){Console.WriteLine("{0}.{1} TotalScore:{2}",query.Id, query.Name, query.TotalScore);}Console.WriteLine();Console.WriteLine("After add ThenBy");//定义查询表达式,找出不及格的学生及其分数var scoreQuery = students.OrderBy((s => s), sortStudentScore).ThenBy(item=>item.Name).Select(item => new {item.Id, item.Name, TotalScore = item.Scores.Sum(score => score) });//输出结果)foreach (var query in scoreQuery){Console.WriteLine("{0}.{1} TotalScore:{2}", query.Id, query.Name, query.TotalScore);}为了说明这个例子,我们让两个学生同名,并且总分也一样,用Id来区别他们,以下是输出结果:Using OrderBy only2.Tina TotalScore:4611.Leon TotalScore:4364.Leon TotalScore:4363.Linda TotalScore:4215.Echo TotalScore:399After add ThenBy2.Tina TotalScore:4611.Leon TotalScore:4364.Leon TotalScore:4363.Linda TotalScore:4215.Echo TotalScore:399我们发现Id 1和Id 4经过ThenBy后,并没有调整顺序。对于像List.Sort<T>这种不稳定排序,相同的值排序后可能打乱掉原有的顺序的。操作符:Reverse描述:Reverse很简单,就是将序列逆序一下原型:
public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source)看个简单的例子吧:
int[] nums = new int[] { 0,1,2,3,4,5 };var evenNums = nums.Reverse();foreach (var evenNum in evenNums){Console.WriteLine(evenNum);}输出的结果为:543210To Be Continue…参考:《Pro.LINQ.Language.Integrated.Query.in.Csharp.2010》
相关文章推荐
- LINQ之非延迟执行标准查询操作符(上)
- LINQ之延迟执行标准查询操作符(下)
- LINQ之非延迟执行标准查询操作符(下)
- LINQ之延迟执行标准查询操作符(上)
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- LINQ 标准的查询操作符 排序 orderby、thenby、Take
- LINQ 标准的查询操作符 分区 Take 、Skip 、TakeWhile 、SkipWhile
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- LINQ入门教程之各种标准查询操作符(一)
- LinQ标准的查询操作符 过滤where,index1,oftype
- Linq to BBJECT之非延时标准查询操作符
- LINQ标准查询操作符学习笔记
- LINQ 标准的查询操作符 排序 orderby、thenby、Take
- LINQ 标准的查询操作符 合计操作符 Count()、Sum()、Min()、Max()、Average()和Aggregate()
- LINQ标准查询操作符
- LinQ标准的查询操作符 符合的from in子句
- LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用
- Linq to OBJECT延时标准查询操作符
- LINQ 标准的查询操作符 合计操作符 Count()、Sum()、Min()、Max()、Average()和Aggregate()
- LinQ标准的查询操作符 排序order,thenby,Take