C#之LINQ中常用的ToLookup,GroupBy, Join之用法总结

一、ToLookup

Lookup

C#之LINQ中常用的ToLookup,GroupBy, Join之用法总结_第1张图片

     ToLookup方法是LINQ常用的扩展方法,有4个重载版本如下


            重载1:ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector)
            重载2:ILookup ToLookup(this IEnumerable source, Func keySelector)
            重载3:ILookup ToLookup(this IEnumerable source, Func keySelector, IEqualityComparer comparer)
            重载4:ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer)
 

  class Student
    {
        public string Name;
        public double Weight;
        public int Age;
    }
    class Program
    {
        static void Main(string[] args)
        {
            LookupExample();
        }
        public static void LookupExample()
        {

            List students = new List { new Student { Name = "张三", Weight = 55.2, Age = 17 },
                                                 new Student { Name = "李三", Weight = 78.7, Age =18 },
                                                 new Student { Name = "刘三", Weight = 64.0, Age = 19 },
                                                 new Student { Name = "周元", Weight = 59.3, Age = 17 },
                                                 new Student { Name = "张大", Weight = 73.8, Age = 18 } };


            //ToLookup是LINQ常用的扩展方法,有4个重载版本如下
            //重载1:ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector)
            //重载2:ILookup ToLookup(this IEnumerable source, Func keySelector)
            //重载3:ILookup ToLookup(this IEnumerable source, Func keySelector, IEqualityComparer comparer)
            //重载4:ILookup ToLookup(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer)
            Lookup lookup =(Lookup)students.ToLookup(p => p.Age,
                                                            p => p.Name + ",体重=" + p.Weight+"kg,年龄="+p.Age+"岁");

            //使用IGrouping 作为循环元素的类型,因为Lookup类实现了IEnumerable>接口
            foreach (IGrouping packageGroup in lookup)
            {

                Console.WriteLine(packageGroup.Key);
                //使用string作为循环元素的类型,因为IGrouping 接口继承于IEnumerable接口
                foreach (string str in packageGroup)
                    Console.WriteLine("    {0}", str);
            }

         
            int count = lookup.Count;

            IEnumerable cgroup = lookup[17];

        
            Console.WriteLine("\n年龄为17岁的学生:");
            foreach (string str in cgroup)
                Console.WriteLine(str);
            bool hasG = lookup.Contains(17);
            Console.Read();
        }

    }

二、GroupBy

     GroupBy的作用是对数据进行分组,分组后的每个对象元素是继承于IGrouping 接口的分组对象。

C#之LINQ中常用的ToLookup,GroupBy, Join之用法总结_第2张图片

 class Student
    {
        public string Name;
        public double Weight;
        public int Age;
        public override string ToString()
        {
            return $"姓名={Name},体重={Weight}Kg,年龄={Age}岁";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            LookupExample();
        }
        public static void LookupExample()
        {

            List students = new List { new Student { Name = "张三", Weight = 55.2, Age = 17 },
                                                 new Student { Name = "李三", Weight = 78.7, Age =18 },
                                                 new Student { Name = "刘三", Weight = 64.0, Age = 19 },
                                                 new Student { Name = "周元", Weight = 59.3, Age = 17 },
                                                 new Student { Name = "张大", Weight = 73.8, Age = 18 } };

            IEnumerable> groups = students.GroupBy(g => g.Age);

//以下语句会得到同样的结果       
//     IEnumerable> groups =from stu in  students Group stu By stu.Age;


            foreach(IGrouping g in groups)
            {
                Console.WriteLine("Key=" + g.Key);
                //由于IGrouping从IEnumerable继承而来,所以下面foreach中可以使用foreach(Student stu in g)
                foreach (Student stu in g)
                {
                    Console.WriteLine(stu.ToString());
                }
            }
 
            Console.Read();
        }

    }

 

GroupBy也存在多个重载,其中常用的一个重载如下:

public static IEnumerable> GroupBy (this IEnumerable source, Func keySelector, Func elementSelector);

使用该重载,则上述例子可以改为如下表示:

  IEnumerable> groups = students.GroupBy(r => r.Age, r => r.Name);

            foreach(IGrouping g in groups)
            {
                Console.WriteLine("Key=" + g.Key);
                //由于IGrouping从IEnumerable继承而来,所以下面foreach中可以使用foreach(string stuStr in g)
                foreach (string stuStr in g)
                {
                    Console.WriteLine(stuStr);
                }
            }

三、Join

     Join方法同样是位于Enumerable类中,是实现IEnumerable接口的所有实现类的扩展方法,具有两个重载:

重载1:public static IEnumerable Join (this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector);

重载2:public static IEnumerable Join (this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer);

类型参数

TOuter

第一个序列中的元素的类型。

TInner

第二个序列中的元素的类型。

TKey

键选择器函数返回的键的类型。

TResult

结果元素的类型。

参数

outer

IEnumerable

要联接的第一个序列。

inner

IEnumerable

要与第一个序列联接的序列。

outerKeySelector

Func

用于从第一个序列的每个元素提取联接键的函数。

innerKeySelector

Func

用于从第二个序列的每个元素提取联接键的函数。

resultSelector

Func

用于从两个匹配元素创建结果元素的函数。

comparer

IEqualityComparer

用于对键进行哈希处理和比较的 IEqualityComparer

返回

IEnumerable

一个 IEnumerable,其中包含通过对两个序列执行内部联接获得的、类型为 TResult 的元素。

此方法是使用延迟执行实现的。 即时返回值是一个对象,该对象存储执行操作所需的所有信息。 此方法表示的查询在枚举对象之前不会执行,方法是直接调用其 GetEnumerator 方法,或者通过 foreach 在 Visual c # 中使用或 For Each 在 Visual Basic 中使用。

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 people = new List { magnus, terry, charlotte };
    List pets = new List { 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);
    }
}

关于Join,又有内连接,左外连接,组连接等方式,可以参考官方文档join clause (C# Reference)

 

 

你可能感兴趣的:(C#语言)