一、查询过滤:where()
void Start()
{
LinqTest();
}
void LinqTest()
{
var news = new[] {
new {Name="张三",Age=19,Address="北京" },
new {Name="李四",Age=22,Address="上海" },
new {Name="王五",Age=34,Address="广州" },
new {Name="赵六",Age=45,Address="杭州" },
new {Name="孙琦",Age=25,Address="深圳" },
new {Name="张玖",Age=45,Address="成都" },
};
news.Where(i => i.Age > 20 && i.Address == "深圳").ToList().ForEach(x=> { Debug.Log(x); });//满足条件的所有对象
var query = from r in news
where r.Name.Contains("张")//满足条件的所有对象
select r;
foreach (var temp in query)
{
Debug.Log(temp.Name);
}
}
//输出结果:{ Name = 孙琦, Age = 25, Address = 深圳 }
//张三
二、选取数据:Select()、SelectMany()
1.select()*:返回一个对象,对数据进行选取或重新组装
void Start()
{
LinqTest();
}
void LinqTest()
{
var news = new[] {
new {Name="张三",Age=19,Address="北京" },
new {Name="李四",Age=22,Address="上海" },
new {Name="王五",Age=34,Address="广州" },
new {Name="赵六",Age=45,Address="杭州" },
new {Name="孙琦",Age=25,Address="深圳" },
new {Name="钱玖",Age=45,Address="成都" },
};
var list = news.Select(i=>new {name=i.Name,age=i.Age });
foreach (var item in list)
{
Debug.Log(item);
}
}
//输出结果:
//Name:张三,Age:19
//Name:李四,Age:22
//Name:王五,Age:34
//Name:赵六,Age:45
//Name:孙琦,Age:25
//Name:钱玖,Age:45
2. SelectMany():类似于数据库的CROSS JOIN ,参考以下例子
void Start()
{
LinqTest();
}
void LinqTest()
{
List<int> list1 = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> list2 = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var query = list1.SelectMany(i => list2, (x, y) => new { result = "" + y + "*" + x + "=" + x * y + "" });
string str = string.Empty;
foreach (var item in query)
{
if (item.result == "9*1=9" || item.result == "9*2=18" ||
item.result == "9*3=27" || item.result == "9*4=36" ||
item.result == "9*5=45" || item.result == "9*6=54" ||
item.result == "9*7=63" || item.result == "9*8=72")
{
str += item.result + "\n";
}
else
{
str += item.result + "\t";
}
}
string[] array = str.Split('\n');
for (int i = 0; i < array.Length; i++)
{
if (i < 3)
{ array[i] = array[i].Substring(0, ((i + 1) * 6)); }
else if (i > 3)
{ array[i] = array[i].Substring(0, ((i + 1) * 6 + i)); }
else
{ array[i] = array[i].Substring(0, ((i + 1) * 6 + 2)); }
Debug.Log(array[i]);
}
}
输出结果:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
三、联接查询:Join()、GroupJoin()
1.Join():数据1.Join(数据2,数据1.key,数据2.key,查询结果)
void Start()
{
LinqTest();
}
void LinqTest()
{
var list1 = new[] {
new {id=1,Name="Jack"},
new {id=2,Name="Wiseman" },
new {id=3,Name="Witt"},
new {id=4,Name="Wolf" }
};
var list2 = new[] {
new { id=2,Name="Woodrow"},
new {id=3,Name="Wooten" },
new {id=5,Name="Hays" },
new {id=8,Name="Hayley" }
};
var query = list1.Join(list2, item1 => item1.id, item2 => item2.id, (item1, item2) => new { item1, item2 });
foreach (var item in query)
{
Debug.Log("ID=" + item.item1.id + " " + "Name=" + item.item1.Name);
Debug.Log("ID=" + item.item1.id + " " + "Name=" + item.item2.Name);
}
}
输出结果:
ID:2,Name:Wiseman
ID:2,Name:Woodrow
ID:3,Name:Witt
ID:3,Name:Wooten
2.GroupJoin():同上,返回数据1的所有元素和根据数据1的key获取的数据2的元素集合,具体请参考以下例子
void Start()
{
LinqTest();
}
void LinqTest()
{
var list1 = new[] {
new {ID=1,Name="张老师" },
new {ID=2,Name="李老师" },
new {ID=3,Name="周老师" },
new {ID=4,Name="王老师" }
};
var list2 = new[] {
new {ID=1,Subject="C#" },
new {ID=2,Subject="Java" },
new {ID=3,Subject="lua" },
new {ID=1,Subject="javacirpt" },
new {ID=2,Subject="C" },
new {ID=4,Subject="C++" },
new {ID=5,Subject="python" },
new {ID=4,Subject="php" },
new {ID=6,Subject="html" }
};
Debug.Log("-------查询所有老师教的课程-------\n\n");
var query = list1.GroupJoin(list2, item1 => item1.ID, item2 => item2.ID, (item1, item2) => new { item1, item2 });
foreach (var item in query)
{
Debug.Log(item.item1.Name + "教" + item.item2.Count() + "门课程,其中有" +
string.Join("、", item.item2.Select(i => i.Subject)));
}
//或者这样写,结果一样:
Debug.Log("--------------------------\n");
var query2 = list1.GroupJoin(list2, item1 => item1.ID, item2 => item2.ID, (item1, item2) =>
new { t = item1.Name, c = item2.Count(), s = string.Join("、", item2.Select(i => i.Subject)) });
foreach (var item in query2)
{
Debug.Log(item.t + "教" + item.c + "门课程,其中有" + item.s);
}
Debug.Log("\n------ - 查询没有老师教的课程------ -\n\n");
var query3 = list2.GroupJoin(list1, item2 => item2.ID, item1 => item1.ID,
(item2, item1) => new { s = item1.Count() == 0 ? item2.Subject : null });
string str = string.Empty;
foreach (var item in query3)
{
if (item.s != null)
{
str += item.s + ",";
}
}
Debug.Log("目前没有老师教的课程有" + str.Substring(0, str.Length - 1));
}
输出结果:
-------查询所有老师教的课程-------
张老师教2门课程,其中有C#、javacirpt
李老师教2门课程,其中有Java、C
周老师教1门课程,其中有lua
王老师教2门课程,其中有C++、php
--------------------------
张老师教2门课程,其中有C#、javacirpt
李老师教2门课程,其中有Java、C
周老师教1门课程,其中有lua
王老师教2门课程,其中有C++、php
-------查询没有老师教的课程-------
目前没有老师教的课程有:python,html
四、分组查询:GroupBy()、ToLookup()
都是根据传入的参数对key进行分组,区别在于GroupBy() 是延迟查询,ToLookup() 不是。
1.GroupBy() 延迟加载
void Start()
{
LinqTest();
}
void LinqTest()
{
var news = new[] {
new {Name="张三",Age=19,Address="上海" },
new {Name="李四",Age=22,Address="上海" },
new {Name="王五",Age=34,Address="广州" },
new {Name="赵六",Age=45,Address="广州" },
new {Name="孙琦",Age=25,Address="深圳" },
new {Name="钱玖",Age=45,Address="深圳" },
new {Name="黄菲",Age=45,Address="北京" }
};
var list1 = news.GroupBy(i => i.Address);
//修改数组最后一条数据
news[6] = new { Name = "黄菲", Age = 45, Address = "上海" };
var list2 = news.GroupBy(i => i.Address);
Debug.Log("-----------list1-----------\n\n");
foreach (var item in list1)
{
Debug.Log("\n---------Address:"+ item.Key+"---------\n");
foreach (var item1 in item)
{
Debug.Log("Name:" + item1.Name + " " + "Age:" + item1.Age);
}
}
Debug.Log("\n\n-----------list2-----------\n\n");
foreach (var item in list2)
{
Debug.Log("\n---------Address:" + item.Key + "---------\n");
foreach (var item1 in item)
{
Console.WriteLine("Name:{0},Age:{1}", item1.Name, item1.Age);
Debug.Log("Name:"+item1.Name+" "+"Age:"+item1.Age);
}
}
}
输出结果:
---------------list1---------------
---------Address:上海---------
Name:张三,Age:19
Name:李四,Age:22
Name:黄菲,Age:45
---------Address:广州---------
Name:王五,Age:34
Name:赵六,Age:45
---------Address:深圳---------
Name:孙琦,Age:25
Name:钱玖,Age:45
---------------list2---------------
---------Address:上海---------
Name:张三,Age:19
Name:李四,Age:22
Name:黄菲,Age:45
---------Address:广州---------
Name:王五,Age:34
Name:赵六,Age:45
---------Address:深圳---------
Name:孙琦,Age:25
Name:钱玖,Age:45
2.ToLookUp()立即加载
将上面代码中的GroupBy 改为 ToLookup
输出结果为:
---------------list1---------------
---------Address:上海---------
Name:张三,Age:19
Name:李四,Age:22
---------Address:广州---------
Name:王五,Age:34
Name:赵六,Age:45
---------Address:深圳---------
Name:孙琦,Age:25
Name:钱玖,Age:45
---------Address:北京---------
Name:黄菲,Age:45
---------------list2---------------
---------Address:上海---------
Name:张三,Age:19
Name:李四,Age:22
Name:黄菲,Age:45
---------Address:广州---------
Name:王五,Age:34
Name:赵六,Age:45
---------Address:深圳---------
Name:孙琦,Age:25
Name:钱玖,Age:45
五、数据排序:OrderBy()、OrderByDescending()、ThenBy()、THenByDescending()
1.OrderBy():根据传入参数对数据源排序(升序)
2.OrderByDescending():与Orderby() 相同,做反向排序(降序)
3.ThenBy():用于多重排序,与OrderBy() 组合,使用于OrderBy() 之后
4.THenByDescending():用于多重排序,与OrderBy() 组合,使用于OrderBy() 之后
void Start()
{
LinqTest();
}
void LinqTest()
{
var list2 = new[] {
new {ID=1,Subject="C#" },
new {ID=2,Subject="Java" },
new {ID=3,Subject="lua" },
new {ID=1,Subject="javacirpt" },
new {ID=2,Subject="C" },
new {ID=4,Subject="C++" },
new {ID=5,Subject="python" },
new {ID=4,Subject="php" },
new {ID=6,Subject="html" }
};
Debug.Log("---------Orderby()、ThenBy()---------\n\n");
var query4 = list2.OrderBy(i => i.ID).ThenBy(i => i.Subject);
foreach (var item in query4)
{
Debug.Log(item);
}
Debug.Log("\n\n---------OrderByDescending()、ThenByDescending()---------\n\n");
var query5 = list2.OrderByDescending(i => i.ID).ThenByDescending(i => i.Subject);
foreach (var item in query5)
{
Debug.Log(item);
}
}
输出结果:
---------Orderby()、ThenBy()---------
{ ID = 1, Subject = C# }
{ ID = 1, Subject = javacirpt }
{ ID = 2, Subject = C }
{ ID = 2, Subject = Java }
{ ID = 3, Subject = lua }
{ ID = 4, Subject = C++ }
{ ID = 4, Subject = php }
{ ID = 5, Subject = python }
{ ID = 6, Subject = html }
---------OrderByDescending()、ThenByDescending()---------
{ ID = 6, Subject = html }
{ ID = 5, Subject = python }
{ ID = 4, Subject = php }
{ ID = 4, Subject = C++ }
{ ID = 3, Subject = lua }
{ ID = 2, Subject = Java }
{ ID = 2, Subject = C }
{ ID = 1, Subject = javacirpt }
{ ID = 1, Subject = C# }
六、集合划分:Take()、Skip()、TakeWhile()、SkipWhile()
//skip 跳过前10项,取剩余元素
//skipWhile 跳过小于 5 元素,取剩余元素
//take 只取前10项,跳过剩余元素
//takeWhile 只取小于 5 元素,跳过剩余元素
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] ints = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
var skip = ints.Skip(10).ToList(); //跳过前 10 项元素,取剩余元素
var skipWhile = ints.SkipWhile(_ => _ < 5).ToList(); //跳过小于 5 元素,取剩余元素
var take = ints.Take(10).ToList(); //只取前 10 项元素,跳过剩余元素
var takeWhile = ints.TakeWhile(_ => _ < 5).ToList(); //只取小于 5 元素,跳过剩余元素
skip.ForEach(_ => Debug.Log(_ + "-")); //10-11-12-13-14-15-16-17-18-19-
skipWhile.ForEach(_ => Debug.Log(_ + "-")); //5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
take.ForEach(_ => Debug.Log(_ + "-")); //0-1-2-3-4-5-6-7-8-9-
takeWhile.ForEach(_ => Debug.Log(_ + "-")); //0-1-2-3-4-
var takeWhile0 = ints.TakeWhile(_ => _ > 5).ToList();//跳过了所有元素,取不到任何元素
Debug.Log("takeWhile0 数量为:" + takeWhile0.Count);// 0
}
输出结果:
10-11-12-13-14-15-16-17-18-19-
5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-
0-1-2-3-4-5-6-7-8-9-
0-1-2-3-4-
takeWhile0 数量为:0
1.Take():返回指定数量的元素
void Start()
{
LinqTest();
}
void LinqTest()
{
var list = new[] { 1,2,3,4,5,6,7,8};
var query = list.Take(5);
Debug.Log("-------------Take-------------");
foreach (var item in query)
{
Debug.Log(item);
}
}
输出结果:
-------------Take-------------
1
2
3
4
5
2.Skip():跳过指定的元素数量,返回剩余元素
void Start()
{
LinqTest();
}
void LinqTest()
{
var list = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var query = list.Skip(2);
Debug.Log("-------------Skip-------------");
foreach (var item in query)
{
Debug.Log(item);
}
}
输出结果:
-------------Skip-------------
3
4
5
6
7
8
3.TakeWhile():返回满足条件的所有元素
注:当第一次检测到条件为false时,将不在检测,返回满足条件的元素
void Start()
{
LinqTest();
}
void LinqTest()
{
var list1 = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
//由于 1>2 为false(不满足条件),所以1 (包括1)后面的所有元素都不会返回
var query1 = list.TakeWhile(i => i > 2);
Debug.Log("-------------TakeWhilei > 2-------------");
foreach (var item in query1)
{
Debug.Log(item);
}
var list2 = new[] { 5,6,7,8,9,10 };
var query2 = list2.TakeWhile(i => i > 4);
Debug.Log("-------------TakeWhilei > 4-------------");
foreach (var item in query2)
{
Debug.Log(item);
}
}
输出结果:
-------------Skip-------------
-------------TakeWhilei > 4-------------
5
6
7
8
9
10
4.First():取数据中满足条件的第一项元素
void Start()
{
LinqTest();
}
void LinqTest()
{
var list = new[] { 5,6,7,8,9,10 };
var query = list.First(i => i > 8);
Debug.Log("-------------First > 8-------------");
Debug.Log(query);
}
输出结果:
-------------First > 8-------------
9
5.Last():满足条件的最后一个
void Start()
{
LinqTest();
}
void LinqTest()
{
List<int>list = new List<int>() { 1, 2, 2, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int a = list.Last();
int b=list.Last(_ => _<8);
Debug.Log(a);
Debug.Log(b);
}
输出结果:
10
7
七、集合运算:Union()、Intersect()、Except()、Distinct()
1.Union():返回两个集合中的并集(两集合重复元素只保留一个)
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] array1 = new int[] { 1, 3, 5, 2, 8, 7, 9 };
int[] array2 = new int[] { 1, 4, 8, 6, 3, 2 };
var result = array1.Union(array2);
Debug.Log("----------Union----------\n");
foreach (var item in result)
{
Debug.Log(item);
}
}
输出结果:
----------Union----------
1 3 5 2 8 7 9 4 6
2.Intersect():返回两个集合的交集
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] array1 = new int[] { 1, 3, 5, 2, 8, 7, 9 };
int[] array2 = new int[] { 1, 4, 8, 6, 3, 2 };
var result = array1.Intersect(array2);
Debug.Log("----------Inersect----------");
foreach (var item in result)
{
Debug.Log(item);
}
}
输出结果:
----------Inersect----------
1 3 2 8
3.Except():
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] array1 = new int[] { 1, 3, 5, 2, 8, 7, 9 };
int[] array2 = new int[] { 1, 4, 8, 6, 3, 2 };
var result = array1.Except(array2);
Debug.Log("----------Inersect----------");
foreach (var item in result)
{
Debug.Log(item);
}
}
输出结果:
----------Inersect----------
5 7 9
4.Distinct():返回集合中非重复的元素
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] int1 = new int[] { 1, 2, 1, 3, 4, 4, 3, 2, 5, 6 };
var list4 = int1.Distinct();
foreach (var item in list4)
{
Console.Write(item+"\t");
}
}
输出结果:
1 2 3 4 5 6
八、汇总聚合:Average()、Max()、Min()、Sum()、Aggregate()、Zip()
Average():计算集合的平均值 只支持int 、long、double、single、deciaml 等值类型
Max():返回集合中的最大值 支持类型同上
Min():返回集合中的最小值 支持类型同上
Sum():计算集合的和 支持类型同上
void Start()
{
LinqTest();
}
void LinqTest()
{
int[] list = new[] { 4, 5, 6, 14, 3, 10 };
Debug.Log("平均值:" + list.Average());
Debug.Log("最大值:" + list.Max());
Debug.Log("最小值:" + list.Min());
Debug.Log("总和:" + list.Sum());
}
输出结果:
平均值:7
最大值:14
最小值:3
总和:42
Aggregate():
1.按照传入的条件对元素进行累计运算
2.可传入种子值作为累计计算的初始值,对返回结果进行处理
参考以下两个实例:
void Start()
{
LinqTest();
}
void LinqTest()
{
//按照字符串长度排序输出
List<string> list = new List<string>() { "red", "yellow", "green", "blue", "paleturquoise", "papayawhip", "peachpuff" };
int count = list.Count;
for (int i = 0; i < count; i++)
{
string a = list.Aggregate((x, y) => x.Length > y.Length ? x : y);
list.Remove(a);
Debug.Log(a);
}
}
输出结果:
paleturquoise
papayawhip
peachpuff
yellow
green
blue
red
Zip():
对两个集合中元素进行合并,若两集合元素数量不一致,则返回结果元素数量与元素数量少的一致(即:一个集合是4个元素,一个是3个,返回结果元素是3个)
参考以下例子
void Start()
{
LinqTest();
}
void LinqTest()
{
List<int> list1 = new List<int> { 19, 20, 34, 42, 22, 14, 25 };
List<string> list2 = new List<string> { "张三", "李四", "王五", "赵二", "牛六", "周玖" };
var result = list1.Zip(list2, (x, y) => string.Format("{0}今年{1}岁了", y, x));
foreach (var item in result)
{
Debug.Log(item);
}
}
输出结果:
张三今年19岁了
李四今年20岁了
王五今年34岁了
趙二今年42岁了
牛六今年22岁了
周玖今年14岁了
九、类型筛选:OfType
void Start()
{
LinqTest();
}
void LinqTest()
{
object[] objects = { 1, 2, 3, 4, 5, "字符1", "字符2", "字符3" };
var intList = objects.OfType<int>().ToList(); //找出类型为 Int 的元素
var stringList = objects.OfType<string>().ToList(); //找出 String 元素
intList.ForEach(_ => Debug.Log(_ + "-")); //1-2-3-4-5-
stringList.ForEach(_ => Debug.Log(_ + "-")); //字符1-字符2-字符3-
}
输出结果:
1-2-3-4-5-
字符1-字符2-字符3-