Linq

Linq

一.初识Linq

Linq中提供了很多集合的扩展方法,配合Lambda能简化数据处理.

比如我们需要获取数组中大于10的数

using System.Linq;

int[] nums = new int[]{3,88,99,55,77,66,15,7};
IEnumerable<int> items = nums.Where(i => i > 10);

Where原理其实如下:

static IEnumerable<int> MyWhere1(IEnumerable<int> items, Func<int, bool> f)
{
    List<int> result = new List<int>();
    foreach (int i in items)
    {
        if (f(i) == true)
        {
            result.Add(i);
        }
    }
    return result;
}

我们可以结合yield,变成流水化的处理

static IEnumerable<int> MyWhere2(IEnumerable<int> items, Func<int, bool> f)
{
    foreach (int i in items)
    {
        if (f(i) == true)
        {
            yield return i;
        }
    }
}

我们顺带提一下var这个声明类型,我们可以使用var让编译器的"类型推断"来简化类型的声明.在Linq中常用,C#的var和JavaScript的var不一样,仍然是强类型的.会根据右边的值推断什么类型.

C#中的弱类型是dynamic

二.Linq的常用扩展方法

我们先创建一批数据

class Employee
{
    public long Id { get; set; }

    public string Name { get; set; }

    public int Age { get; set; }

    public bool Gender { get; set; }

    public int Salary { get; set; }

    public override string ToString()
    {
        return $"Id={Id},Name={Name},Age={Age},Gender={Gender},Salary={Salary}";
    }
}

static void Main(string[] args)
{
    List<Employee> list = new List<Employee>();
    list.Add(new Employee {Id = 1, Name = "jerry", Age = 28, Gender = true, Salary = 5000});
    list.Add(new Employee { Id = 2, Name = "jim", Age = 33, Gender = true, Salary = 3000 });
    list.Add(new Employee { Id = 3, Name = "lily", Age = 35, Gender = false, Salary = 9000 });
    list.Add(new Employee { Id = 4, Name = "lucy", Age = 16, Gender = false, Salary = 2000 });
    list.Add(new Employee { Id = 5, Name = "kimi", Age = 25, Gender = true, Salary = 1000 });
    list.Add(new Employee { Id = 6, Name = "nancy", Age = 35, Gender = false, Salary = 8000 });
    list.Add(new Employee { Id = 7, Name = "zack", Age = 35, Gender = true, Salary = 8500 });
    list.Add(new Employee { Id = 8, Name = "jack", Age = 33, Gender = true, Salary = 8000 });
}

1.Where方法

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

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

IEnumerable<Employee> items1 = list.Where(e => e.Age > 30);
foreach (Employee e in items1)
{
    Console.WriteLine(e);
}

2.Count()方法

获取数据条数

Console.WriteLine(list.Count());
Console.WriteLine(list.Count(e => e.Age>20));
Console.WriteLine(list.Count(e => e.Age > 20 && e.Salary > 8000));

3.Any()方法

是否至少有一条数据

Console.WriteLine(list.Any(e => e.Salary > 300000));
Console.WriteLine(list.Any(e => e.Salary > 5000));

4.获取一条数据方法

Single():有且只有一条满足要求的数据

Employee e1 = list.Where(e => e.Name == "jerry").Single();
Console.WriteLine(e1);

SingleOrDefault():最多只有一条满足要求的数据

Employee e2 = list.SingleOrDefault(e => e.Name == "jim");
Console.WriteLine(e2);

First():至少有一条,返回第一条

Employee e3 = list.First(e => e.Age > 30);
Console.WriteLine(e3);

FirstOrDefault():返回第一条或者默认值

Employee e4 = list.FirstOrDefault(e => e.Age > 30);
Console.WriteLine(e4);

5.排序方法

Order(): 对数据正序排序

IOrderedEnumerable<Employee> orderedEnumerable1 = list.OrderBy(e.Name[e.Name.Length - 1]);
foreach (Employee e in orderedEnumerable1)
{
    Console.WriteLine(e);
}

OrderByDescending(): 对数据倒序排序

IOrderedEnumerable<Employee> orderedEnumerable2 = list.OrderByDescending(e => e.Age).ThenBy(e => e.Salary);//先按年龄再按工资排序
foreach (Employee e in orderedEnumerable2)
{
    Console.WriteLine(e);
}

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

Skip(n):跳过n条数据

Take(n):获取n条数据

IEnumerable<Employee> enumerable3 = list.Skip(3).Take(2);
foreach (Employee e in enumerable3)
{
    Console.WriteLine(e);
}

7.聚合函数

Max(),Min(),Average(),Sum(),Count()

Linq中所有的扩展方法几乎都是针对

8.分组

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

例子:根据年龄分组,获取每组人数,最高工资,平均工资

var items = list.GroupBy(e => e.Age);
foreach (IGrouping<int, Employee> g in items)
{
    Console.WriteLine(g.Key);
    foreach (Employee e in g)
    {
        Console.WriteLine(e);
    }

    Console.WriteLine("**********");
}

9.投影

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

var items2 = 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 items2)
{
    Console.WriteLine(e.NianLing + ","+e.MaxS+","+e.MinS+","+e.RenShu);
}

10.集合转换

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

var items3 = list.Where(e => e.Salary > 6000);
List<Employee> list1 = items3.ToList();
Employee[] array = items3.ToArray();

11.链式调用

Where,Select,OrderBy,GroupBy,Take,Skip,等返回值都是IEnumerable类型,所以可以链式调用.

var items4 = list.Where(e => e.Id > 2)
                .GroupBy(e => e.Age)
                .OrderBy(g => g.Key)
                .Take(3)
                .Select(g => new {NL = g.Key, RS = g.Count(), PJ = g.Average(e =>e.Salary)});
foreach (var i in items4)
{
    Console.WriteLine(i.NL+","+i.RS+","+i.PJ);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值