C#基础_学习笔记--LINQ常用扩展方法

LINQ:常用扩展方法1

Linq中提供了大量类似Where的扩展方法,简化了数据处理。大部分都在System.Linq命名空间中。

数组、List、Dictionary、Set等都实现了IEnumerable,所以都可以使用IEnumerable扩展方法,可以用linq;

  • Where方法

    每一项数据都会经过predicate的测试,如果针对一个元素,predicate执行的返回值为true,那么这个元素就会放到返回值中。

  • Where参数

    是一个lambda表达式格式的匿名方法,方法的参数e表示当前判断的元素对象。参数的名字不一定非要叫e,不过一般lambda表达式中的变量名长度都不长。

var items1 = list.Where(e => e.Age > 30);//返回IEnumerable
  • Count()

    满足条件的个数

list.Count();
list.Count(x => x.Age > 20);
list.Count(x => x.Age > 20 && x.Salary > 8000);
  • Any()

    判断是否有一条数据,返回bool

bool a = list.Any();//true
bool b = list.Any(x => x.Salary > 300000);//false

也可以用Count来判断,但如果只是判断是否有,Any的效率会更高;


LINQ:常用扩展方法2

获取一条数据(是否带参数的两种写法)

  • Single

    有且只有一条满足要求的数据;只能为一个,不然报错;

  • SingleOrDefault

    最多只有一条满足要求的数据;0个或者1个可以,多于一个会报错;

  • First

    至少有一条,返回第一条;

  • FirstOrDefault

    返回第一条或者默认值;

//两种写法都行
var e1 = list.Single(x => x.Name == "Jerry");
var e2 = list.Where(x => x.Name == "Jerry").Single();

排序:对原数据无影响

  • OrderBy

    对数据正序排序;

  • OrderByDescending

    倒序排序;

list.Order(x => x.Age);

int[] nums = new int[]{3,9,6,4,10,7};
var nums2 = nums.OrderBy(i => i);

//随机排序
Random rand = new Random();
var items2 = list.OrderByDescending(e => rand.Next());

//根据Name的最后一个字母排序
var items3 = list.OrderByDescending(e => e.Name[e.Name.Length - 1]);

多规则排序

var items = list.OrderBy(e=>e.Age).ThenBy(e=>e.Salary);
var items2 = list.OrderBy(e=>e.Age).ThenByDescending(e=>e.Salary);

限制结果集,获取部分数据

Skip(n)跳过n条数据,Take(n)获取n条数据。

  • 案例:获取从第3条开始获取3条数据
var orderedItems1 = list.Skip(2).Take(3);

Skip()、Take()也可以单独使用。

  • 案例:分页显示数据

    一页有20条数据(pageSize),当前页为第2页(Current)

    list.Skip(pageSize * (Current -1)).Take(pageSize);
    

LINQ:常用扩展方法3

聚合函数

Max()、Min()、Average()、Sum()、Count()

linq中所有的扩展方法几乎都是针对IEnumerable接口的,而几乎所有能返回集合的都返回IEnumerable,所以是可以把几乎所有方法“链式使用”的。

list.Where(e=>e.Age>30).Min(e=>e.Salary);
int a = list.Max(x=>x.Age);//返回list中年龄的最大值
string s = list.Max(e=>e.Name);//字符串的大小比较

分组

GroupBy()

参数是分组条件表达式,返回值为IGrouping<TKey,TSource>类型的泛型IEnumerable,也就是每一组以一个IGrouping对象的形式返回。IGrouping是一个继承自IEnumerable的接口,IGrouping中Key属性表示这一组的分组数据的值。

IEnumerable<IGrouping<int,Employee>> items = list.GroupBy(x=>x.Age);
foreach(IGrouping<int,Employee> g in items)
{
    Console.WriteLine(g.Key);//g.Key为分组的条件,这里就是Age
    Console.WriteLine("最大工资:" + g.Max(x=>x.Salary))
    foreach(Employee e in g)
    {
        Console.WriteLine(e);
    }
    Console.WriteLine("*******************");
}

LINQ:常用扩展方法4

投影

  • Select

把集合中的每一项转换为另外一种类型。

//只取年龄
IEnumerable<int> ages = list.Select(e=>e.Age);
//只取name
var names = list.Select(e=>e.Name);
//
var items1 = list.Select(e=>e.Name +""+ e.Age);
//
var items2 = list.Where(x=>x.Age>30).Select(x=>x.Name);

匿名类型

var obj1 = new {Name="ddd",Salary=3000}
Console.WriteLine(obj1.Name);//"ddd"
Console.WriteLine(obj1.Salary);//3000

匿名类型在编译后,会自动生成一个类型,名字由编译器自动生成;

投影与匿名类型

例1:

var items = list.Select(e=>new {XingMing = e.Name,NianLing = e.Age,Xingbie=e.Gender?"男":"女"});
foreach(var i in items)
{
    Console.WriteLine(i.NianLing + i.XingBie);
}

例2:年龄分组,并获得工资的最值,以及统计人数等

public class employee
{
    public int Age { get; set; }
    public int Salary { get; set; }
    public bool Gender { get; set; }
}
var list = new List<employee>();
list.Add(new employee{Age = 20,Salary =3000,Gender = true});
list.Add(new employee{Age = 20,Salary =9000,Gender = false});
list.Add(new employee{Age = 50,Salary =8000,Gender = true});
list.Add(new employee{Age = 50,Salary =1000,Gender = false });
list.Add(new employee{Age = 60,Salary =5400,Gender = true});
list.Add(new employee{Age = 60,Salary =7800,Gender = false });
list.Add(new employee{Age = 20,Salary =6700,Gender = true});

var items1 = list.GroupBy(e=>e.Age).Select(g=>new 
             {NianLing = g.Key,MaxS = g.Max(e=>e.Salary),MinS = g.Min(e=>e.Salary),RenShu = g.Count()});
foreach(var e in items1)
{
    Console.WriteLine(e.NianLing + "," + e.MaxS +","+ e.MinS + "," + e.RenShu);
}

//结果
20,9000,3000,3
50,8000,1000,2
60,7800,5400,2

LINQ:链式调用

集合转换

有一些地方需要数组类型或者List类型的变量,我们可以用ToArray()方法和ToList()分别把IEnumerable转换为数组类型和List类型。

IEnumerable<employee> items2 = list.Where(x=>x.Salary>5000);
List<employee> list2 = items2.ToList();
employee[] array2 = items2.ToArray();

例1:

获取id>2的数据,然后按照Age分组,并且把分组按照Age排序,然后取出前3条,最后再投影取得年龄、人数、平均工资

var list = new List<employee>();
list.Add(new employee{ Id = 1, Age = 20,Salary =3000,Gender = true});
list.Add(new employee{ Id = 2, Age = 20,Salary =9000,Gender = false});
list.Add(new employee{ Id = 3, Age = 50,Salary =8000,Gender = true});
list.Add(new employee{ Id = 4, Age = 50,Salary =1000,Gender = false });
list.Add(new employee{ Id = 5, Age = 60,Salary =5400,Gender = true});
list.Add(new employee{ Id = 6, Age = 60,Salary =7800,Gender = false });
list.Add(new employee{ Id = 7, Age = 20,Salary =6700,Gender = true});

var result = list.Where(x => x.Id > 2).GroupBy(x => x.Age).OrderBy(x => x.Key).Take(3);
//result类型:IEnumerable<IGrouping<int,employee>>
var items = result.Select(x => new { NL = x.Key, RS = x.Count(), pingjun = x.Average(g => g.Salary) });
foreach (var i in items)
{
    Console.WriteLine(i.NL + "," + i.RS +"," + i.pingjun);
}

//结果
20,1,6700
50,2,4500
60,2,6600

上一篇:C#调用C++ 类型转换


下一篇:指针偏移