C#Linq常用方法

发布时间 2023-12-12 18:09:01作者: 落花流水1173

Linq一般都在System.Linq命名空间下,是针对IEnumable类型集合的扩展方法,配合Lambda能简化数据的处理

where(Func<T,bool>):根据条件过滤,实现原理如下

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
            var result= list.MyWhere(x => x > 5);
            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }
    }

    public static class EnumableExtension
    {
        public static IEnumerable<T> MyWhere(this IEnumerable<T>Source,Func<int,bool> filter)
        {
           IEnumerable<T> result = new List<T>();
           foreach (int i in list)
            {
                if(filter(i)) yield return i;
            }
        }
    }
}

 

2、Count():集合中元素个数

3、Count(Func<T,bool>):集合中满足条件的个数,实现原理如下:

   public static int MyCount<T>(this IEnumerable<T> Source,Func<T,bool> filter)
   {
       int count = 0;
       foreach (var item in Source)
       {
           if (filter(item)) count++;
       }
       return count;
   }

  static void Main(string[] args)
  {
      List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
     
      Console.WriteLine(list.MyCount(x=> x > 5));
  }

4、Any():判断集合中是否包含任何元素,返回Bool

5、Any(Func<T,bool>):判断集合中是否有包含满足条件的元素,返回bool,实现原理如下:

 public static bool MyAny<T>(this IEnumerable<T> Source,Func<T,bool> filter)
 {
    
     foreach (var item in Source)
     {
         if(filter(item))
         {
            return true;
         }
     }
     return false;
 }

static void Main(string[] args)
{
    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
    var result= list.MyAny(x => x > 5);
    Console.WriteLine(result);
}

6、Singe(Funce<T,bool>)、SingleOrDefault(Funce<T,bool>)、First(Funce<T,bool>)、FistOrDefult(Func<T,bool>)、Last(Funce<T,bool>)、LastOrDefult(Funce<T,bool>)的区别

 Singe(Funce<T,bool>)的实现原理如下:

 public static T MySinge<T>(this IEnumerable<T> Source, Func<T,bool> filter)
 {
     //1、集合为Null时,引发异常
     //2、集合不包含任何满足条件的元素时,引发异常
     //3、集合包含一个满足条件的元素时,返回改元素
     //4、集合包含不止一个满足条件元素时,引发异常
     if(Source == null)
     {
         throw new Exception("集合为空");
     }

     int count = 0;
     T result=default(T);
     foreach (var item in Source)
     {
         if(filter(item))
         {
             count += 1;
             if(count>1)
             {
                 throw new Exception("不止一个元素满足条件");
             }
             else
             {
                 result = item;
             }
         }
     }
     if(count==0)
     {
         throw new Exception("没有满足条件的元素");
     }
     return result;
     
 }

7、排序相关,返回类型是IOrderedEnumerable,IOrderedEnumerable也是继承于IEnumerable,所以可以继续执行Linq语句,形成链式查询

  OrderBy():正序排序
  OrderByDescending():倒序排序

  IOrderedEnumerable.ThenBy():排序之后再正序
  IOrderedEnumerable.ThenByDescending():排序之后再降序

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

  Skip(int):跳过n条数据

  Take(int):获取n条数据

9、GroupBy():分组,类似于SQL的GroupBy

10、Select:投影,把集合中的每一项转换成另外一种类型

       可以结合匿名类型方便的获取到想要的数据,匿名类型:var obj1=new {Name="AAA",Salary=3000};只能用var定义

static void Main(string[] args)
{
    List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
    var list1=  list.Select(x => new { Id = x });
    foreach (var item in list1)
    {
        Console.WriteLine(item.Id);
    }
}

11、GroupBy():分组,类似于SQL的GroupBy

12、聚合函数:    

  Max():获取最大值
  Min():获取最小值
  Average():求平均值
  Sum():求和
  Count():个数

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

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 });
//获取Id > 2的数据,然后按照Age分组, 并且把分组按照Age排序,然后取出前3条,最后再投影取得年龄、人数、平均工资
var aaa= list.Where(x => x.Id > 2).GroupBy(x => x.Age).OrderBy(x => x.Key).Take(3).Select(x => new { Age = x.Key, Count = x.Count(), Av = x.Average(y => y.Salary) });
foreach (var x in aaa)
{
    Console.WriteLine($"{x.Age},{x.Count},{x.Av}");
}

结果: