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的作用是对数据进行分组,分组后的每个对象元素是继承于IGrouping
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
使用该重载,则上述例子可以改为如下表示:
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
重载2:public static IEnumerable
类型参数
TOuter
第一个序列中的元素的类型。
TInner
第二个序列中的元素的类型。
TKey
键选择器函数返回的键的类型。
TResult
结果元素的类型。
参数
outer
IEnumerable
要联接的第一个序列。
inner
IEnumerable
要与第一个序列联接的序列。
outerKeySelector
Func
用于从第一个序列的每个元素提取联接键的函数。
innerKeySelector
Func
用于从第二个序列的每个元素提取联接键的函数。
resultSelector
Func
用于从两个匹配元素创建结果元素的函数。
comparer
IEqualityComparer
用于对键进行哈希处理和比较的 IEqualityComparer
返回
IEnumerable
一个 IEnumerableTResult
的元素。
此方法是使用延迟执行实现的。 即时返回值是一个对象,该对象存储执行操作所需的所有信息。 此方法表示的查询在枚举对象之前不会执行,方法是直接调用其 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)