Linq中关键字的作用及用法
1.All:确定序列中的所有元素是否都满足条件。如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true;否则为 false。
Demo:
此示例使用 All 确定数组是否仅包含奇数。
public void Linq70()
{
//创建一个数组
int[] numbers = { 1, 11, 3, 19, 41, 65, 19 };
//调用All方法
bool onlyOdd = numbers.All(n => n % 2 == 1);
//输出结果
Console.WriteLine("这个数组仅包含奇数: {0}", onlyOdd);
}
输出结果:这个数组仅包含奇数:true
2.Any:确定序列是否符合某条件元素,如果源序列中有任一元素符合条件,则为 true;否则为 false。
Demo:
此示例使用 Any 确定数组中是否有任何单词包含子字符串“ei”。
public void Linq67()
{
//创建数组
string[] words = { "believe", "relief", "receipt", "field" };
//调用Any方法
bool iAfterE = words.Any(w => w.Contains("ei"));
//输出结果
Console.WriteLine("数组中有一个元素包含“ei”: {0}", iAfterE);
}
输出结果:数组中有一个元素包含“ei”: true
3.where: 子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素。它将一个布尔条件(“谓词”)应用于每个源元素(由范围变量引用),并返回满足指定条件的元素。一个查询表达式可以包含多个 where 子句,一个子句可以包含多个谓词子表达式。
Demo1:
在下面的示例中,where 子句筛选出除小于五的数字外的所有数字。如果移除 where 子句,则会返回数据源中的所有数字。
public void Linq1()
{
//定义一个简单的、支持Ienumerable的数据源,这里是一个数组
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//定义查询语句,where用于where子句
var lowNums =
from n in numbers
where n < 5
select n;
//执行查询语句
foreach (var x in lowNums)
{
Console.Write (x+” ”);
}
}
输出结果:4 1 3 2 0
Demo2:
在单一 where 子句内,可以使用 && 和 || 运算符根据需要指定任意多个条件。
public void Linq2()
{
//定义数据源
List<Product> products = GetProductList();
//定义查询子句
var expensiveInStockProducts =
from p in products
where p.UnitsInStock > 0 && p.UnitPrice > 3.00M
select p;
//执行查询语句
foreach (var product in expensiveInStockProducts)
{
Console.WriteLine(product.ProductName);
}
}
Demo3:
Where子句内可以带索引,下面的子句返回其名称短于其值的数字。
public void Linq5()
{
//定义数据源
string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
//语句
var shortDigits = digits.Where((digit, index) => digit.Length < index);
//执行
foreach (var d in shortDigits)
{
Console.WriteLine("The word {0} is shorter than its value.", d);
}
}
备注:where 子句是一种筛选机制。除了不能是第一个或最后一个子句外,它几乎可以放在查询表达式中的任何位置。where 子句可以出现在 group 子句的前面或后面,具体情况取决于是必须在对源元素进行分组之前还是之后来筛选源元素。
4. select: 在查询表达式中,select 子句可以指定将在执行查询时产生的值的类型。该子句的结果将基于前面所有子句的计算结果以及 select 子句本身中的所有表达式。查询表达式必须以 select 子句或 group 子句结束。
Demo1:
下面示例使用 Select 生成一个整数序列,其中每个整数都比其中每个整数都比现有整数数组中的相应整数大一。
public void Linq6()
{
//创建数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//创建查询语句
var numsPlusOne =
from n in numbers
select n + 1;
//执行查询语句
foreach (var i in numsPlusOne)
{
Console.Write (i+” “);
}
}
输出结果:6 5 2 4 10 9 7 8 3 1
Demo2:
下面的示例使用 Select 生成表示整数序列文本形式的序列。
public void Linq8()
{
//定义数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
//创建查询语句
var textNums =
from n in numbers
select strings[n];
//执行查询语句
foreach (var s in textNums)
{
Console.Write (s+” “);
}
}
输出结果:five four one three nine eight six seven two zero
5. take:方法返回的是从序列的开头到指定数量的连续元素。
public void Linq20()
{
//创建数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//取前三个并升序排列
var first3Numbers = numbers.Take(3).OrderBy(num=>num);
//执行
Console.WriteLine("前三个数按升序排序后是:");
foreach (var n in first3Numbers)
{
Console.Write(n+” “);
}
}
输出结果:前三个数按升序排序后是:1 4 5
6.Skip:返回从指定数量之后的所有连续元素
public void Linq22()
{
//定义数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//调用Skip方法
var allButFirst4Numbers = numbers.Skip(4);
Console.WriteLine("除了前四个数的所有数字是:");
//执行
foreach (var n in allButFirst4Numbers)
{
Console.Write (n+” “);
}
}
输出结果:除了前四个数的所有数字是: 9 8 6 7 2 0
7.takewhile:只要满足指定的条件,在条件满足的情况下从序列的开头返回元素。
Demo2:
此示例使用 TakeWhile 返回从数组开头起的所有元素,直到碰到不小于 6 的数字。
public void Linq24()
{
//创建数组
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//调用TakeWhile
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
Console.Write("元素小于6且在六之前的数是:"+" ");
//执行输出结果
foreach (var n in firstNumbersLessThan6)
{
Console.Write(n+" ");
}
}
输出结果:元素小于6且在6之前的数是: 5 4 1 3
8.skipwhile:只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素。
Demo:
此示例使用 SkipWhile 获取数组中从第一个能被 3 整除的元素开始的所有元素。
public void Linq26()
{
//创建数组
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//调用
var allButFirst3Numbers = numbers.SkipWhile(n => n % 3 != 0);
Console.WriteLine("所有从可以被3整除开始的元素为:");
foreach (var n in allButFirst3Numbers)
{
Console.Write(n+" ");
}
}
输出结果:所有从可以被3整除开始的元素为:3 9 8 6 7 2 0
9.sum:计算十进制数序列的和,这些数是通过对输入序列中的每个元素调用转换函数得来的。
public void Linq78()
{
//定义数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//执行 numbers中所有元素的和
double numSum = numbers.Sum();
//输出结果
Console.WriteLine("The sum of the numbers is {0}.", numSum);
}
10.Max:返回序列中的最大值。
Demo1:
此示例使用Max获取数组中最大的数字
public void Linq85()
{
//定义数据源
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//执行 返回序列中的最大值
int maxNum = numbers.Max();
//输出结果
Console.WriteLine("最大的数是:{0}", maxNum);
}
输出结果:最大数是:9
Demo2:
此示例使用 Max 获取数组中最长单词的长度。
public void Linq86()
{
//定义数据源
string[] words = { "cherry", "apple", "blueberry" };
//执行 返回序列中最长单词的长度
int longestLength = words.Max(w => w.Length);
Console.WriteLine("最长的单词是 {0} 个字符长。", longestLength);
}
输出结果:最长单词是 9 个字符长
11.Average:返回十进制数字序列的平均值
Demo1:
此示例使用 Average 获取数组中所有数字的平均值。
public void Linq89()
{
//创建一个数组
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
//调用Average方法
double averageNum = numbers.Average();
//输出结果
Console.WriteLine("平均数为{0}.", averageNum);
}
输出结果:平均数为4.5
12.Concat:用于连接两个序列
Demo:
此示例使用 Concat 创建一个序列,其中依次包含每个数组的值。
public void Linq94()
{
//创建两个数组序列
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
//调用Concat方法连接numberA和numberB,并组成一个新的序列
var allNumbers = numbersA.Concat(numbersB);
Console.Write("两个数组中的所有元素为:"+" ");
//输出结果
foreach (var n in allNumbers)
{
Console.Write(n+" ");
}
}
输出结果:两个数组中的所有元素为:0 2 4 5 6 8 9 1 3 5 7 8
13.SequenceEqual:通过使用相应类型的默认相等比较器对序列的元素进行比较,以确定两个序列是否相等。如果根据相应类型的默认相等比较器,两个源序列的长度相等,其且其相应元素也都相等,则为 true;否则为 false。
Demo:
此示例使用 SequenceEqual 查看两个序列中是否所有元素以相同顺序匹配。
public void Linq96()
{
//创建两个数组序列
var wordsA = new string[] { "cherry", "apple", "blueberry" };
var wordsB = new string[] { "cherry", "apple", "blueberry" };
//调用SequenceEqual方法进行比较wordsA和wordsB
bool match = wordsA.SequenceEqual(wordsB);
//输出比较结果
Console.WriteLine("两个序列完全匹配为: {0}", match);
}
输出结果:两个序列完全匹配为:True
14.Count:返回元素的数量
Demo:
此示例使用 Count 获取 300 的唯一因子的数量。
public void Linq73()
{
//创建一个数组序列
int[] factorsOf300 = { 2, 2, 3, 5, 5 };
//调用Distinct方法除去重复,并用Count方法计数
int uniqueFactors = factorsOf300.Distinct().Count();
//输出结果
Console.WriteLine("数组中有 {0}个300的唯一因子", uniqueFactors);
}
输出结果:数组中有3个300的唯一因子
15. Aggregate:(1)对序列应用累加器函数,返回累加器的最终值。
(2)对集合值执行自定义聚合运算
Demo1:
此示例使用 Aggregate 创建数组的连乘,计算所有元素的总乘积。
public void Linq92()
{
//创建一个数组序列
double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
//调用Aggregate方法
double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor);
Console.WriteLine("所有数的总乘积为: {0}", product);
}
输出结果:所有数的总乘积为:88.33081
Demo2:
此示例使用 Aggregate查询名称,每个名称之间用顿号连接
public void Aggregate()
{
Product[] pro = {
new Product{ Name="哈哈", Age=45},
new Product{ Name="哇哈哈", Age=55},
new Product{ Name="嘿嘿", Age=45},
};
var result = pro.Select(product => product.Name)
.ToArray()
.Aggregate((current, next) => String.Format("{0}、{1}", current, next));
Console.WriteLine(result);
}
输出结果:哈哈、娃哈哈、嘿嘿
16.Range:生成指定范围内的整数的序列。
Demo:
此示例使用 Range 生成一个从 100 到 149 的数字序列, 用于查找该范围内的哪些数字是奇数和偶数。
public void Linq65()
{
//调用Range方法创建指定的范围序列
var numbers =
from n in Enumerable.Range(10, 5)
select new
{ Number = n, OddEven = n % 2 == 1 ? "奇数" : "偶数" };
//输出结果
foreach (var n in numbers)
{
Console.WriteLine("数 {0} 是 {1}.", n.Number, n.OddEven);
}
}
输出结果:数 10 是 偶数
数 11是 奇数
数 12 是 偶数
数 13 是 奇数
数 14 是 偶数
注意:Range(10,5)中10是表示序列中第一个整数的值,5表示生成序列整数的数目。
17. Repeat:它返回的是一个序列,它的元素是指定值的副本。Repeat有两个参数即Repeat(value,count) value是它在序列中要进行多次复制的对象,count是复制的次数。
Demo:
此示例使用 Repeat 生成包含数字 7 十次的序列。
public void Linq66()
{
//调用Repeat方法,把7复制10次
var numbers = Enumerable.Repeat(7, 10);
//输出结果
foreach (var n in numbers)
{
Console.Write(n+" ");
}
}
输出结果:7 7 7 7 7 7 7 7 7 7
18. First:返回序列中的第一个元素。
Demo:
此示例使用 First 将数字中的第一个数返回
public void LinqSample()
{
//创建一个序列
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 435, 67, 12, 19 };
//调用First方法
int first = numbers.First();
//输出结果
Console.WriteLine(first);
}
输出结果:9
19. Cast: 将非泛型序列转换为范型的序列。
Demo:
此示例使用Cast将一个非泛型的序列转换成泛型,并使用对应的方法
public void Cast()
{
//创建一个序列
object[] obj = {43,43,4,56,5,6,57,65656,78,8};
//将一个非泛型的序列转换为Int型的泛型,求最大值
var result = obj.Cast<int>().Max();
//输出结果
Console.WriteLine(result);
}
输出结果:65656
20.OfType: 在序列中挑出指定类型的元素转换到泛型序列中
Demo:
此示例使用OfType挑出int类型的数字转换到泛型序列中
public void OfType(){
//创建一个序列
object[] obj = {443,67778,"dede","rxvfvf",65};
//把obj中的int型的元素取出
var para = obj.OfType<int>();
foreach (var element in para)
{
//输出结果
Console.WriteLine (element);
}
}
输出结果:443 67778 65
21.Single: 取得序列的唯一一个元素(保证序列有且只有一个元素),否则,报错
Demo:
此示例将检验序列中是否是否有且只有一个元素
public void Single()
{
int[] value = { 32 };
//调用Single方法
var i = value.Single();
Console.WriteLine(i);
}
输出结果:32
public void Single()
{
int[] value = { 32,45 };
//调用Single方法
var i = value.Single();
Console.WriteLine(i);
}
输出结果:报错:
6InvalidOperationException |
序列包含一个以上的元素 |
22. Intersect:获得两个序列的交集
Demo:
此示例将显示两序列公有的元素
public void Intersect()
{
//创建序列
int[] i1 = { 3, 5, 78, 434, 435, 876 };
int[] i2 = { 3, 435 };
//调用方法进行比较
var result = i1.Intersect(i2);
foreach (var element in result)
{
//输出结果
Console.WriteLine(element);
}
}
输出结果:3 435
23. Except:获得两个序列的差集
Demo:
此示例将显示序列1与序列2的差集(序列2与序列1进行比较,序列2中没有的部分)
public void Except()
{
//创建序列
int[] i1 = { 3, 5, 78, 434, 435, 876 };
int[] i2 = { 3, 435 };
//调用方法进行比较 输出的是Except(XX)中没有的
var result = i1.Except(i2);
foreach (var element in result)
{
//输出结果
Console.WriteLine(element);
}
}
输出结果: 5 78 434 876
24. Union:获得两个序列的并集
Demo:
此示例将显示两个序列全部的部分
public void Union()
{
//创建序列
int[] i1 = { 3, 5, 78, 434, 435, 876 };
int[] i2 = { 3, 435 };
//调用方法进行比较
var result = i1.Union(i2);
foreach (var element in result)
{
//输出结果
Console.WriteLine(element);
}
}
输出结果: 3 5 78 434 435 876
25. Distinct:取得序列中的非重复元素,序列中重复的元素只输出一次
Demo:
此示例将显示序列中重复的元素只输出一次
public void Distinct()
{
//创建一个序列
int[] para = {43, 87,87,343,43,43};
//调用方法
var result = para.Distinct();
foreach (var element in result)
{
//输出结果
Console.WriteLine(element);
}
}
输出结果:43 87 343
26. Reverse:序列中的元素按照从后到前的循序反转
Demo:
此示例将把数组中的数字反转进行输出
public void Reverse()
{
//创建一个序列
int[] i1 = { 3, 5, 78, 434, 435, 876 };
//调用方法
var result = i1.Reverse();
Console.WriteLine (result);
}
输出结果:876 435 434 78 5 3
26. SelectMany:将多个from子句组合起来的功能,它将每个对象的结果合并成单个序列
Demo:
此示例将对象中名字输出
public void SelectMany()
{
//查询语法
Product[] pro = {
new Product{ Name="哈哈", Age=45},
new Product{ Name="哇哈哈", Age=45},
new Product{ Name="嘿嘿", Age=45},
};
var result = from p in pro
from n in p.Name
select n;
foreach (var item in result)
{
Console.Write(item);
}
//方法语法
var r = pro.SelectMany(n=>n.Name);
foreach (var item in r)
{
Console.Write(item);
}
}
输出结果:哈哈哇哈哈嘿嘿
27. GroupBy:根据一个特定的值将序列中的元素进行分组
Demo:
此示例将根据年龄进行分组
public void GroupBy()
{
//查询语法
Product[] pro = {
new Product{ Name="哈哈", Age=45},
new Product{ Name="哇哈哈", Age=55},
new Product{ Name="嘿嘿", Age=45}, };
var g = from p in pro
group p by p.Age;
foreach (var items in g)
{
Console.WriteLine(items.Key);
foreach (var item in items)
{
Console.WriteLine(item.Name);
}
}
//方法语法
var product = pro.GroupBy(grou=>grou.Age);
输出结果:45
哈哈
嘿嘿
55
哇哈哈
28. ElementAt:返回序列中指定索引处的元素
Demo:
此示例将索引为3的字符输出
public void ElementAt()
{
//查询语法
string str = "WelcomeToJining";
var result = str.ElementAt(3);
Console.WriteLine(result);
}
输出结果:c
29. Contains:用来确定序列是否包含满足指定条件的元素。如果有返回true,否则返回false。
Demo:
此示例将查询h是否在字符串中
public void Contains()
{
//查询语法
string str = "BeiJing";
var result = str.Contains('h');
Console.WriteLine(result);
}
输出结果:false
30.ToDictionary:根据指定的键选择器函数,从IEnumerable<T>创建一个Dictionary<TKey, TValue>
Demo:
此示例将查询到的产品类别集合转换为Dictionary< ID,名称>的键-值集合
public void ToDictionary()
{
//查询语法
Product[] pro = {
new Product{ ID=1, Name="哈哈", Age=45},
new Product{ ID=2,Name="哇哈哈", Age=55},
new Product{ ID=3,Name="嘿嘿", Age=45},
};
var result = pro.ToDictionary(
p=>p.ID,
p=>p.Name
);
foreach (var item in result)
{
Console.WriteLine("key{0}-value{1}",item.Key,item.Value);
}
}
输出结果:key1-value哈哈
Key2-value哇哈哈
Key3-value嘿嘿
30.ToLookUp:创建一个 Lookup<TKey, TElement>对象,这是一个one-to-many集合,一个Key可以对应多个Value
Demo:
此示例将以ID作为Key调用了ToLookup方法,然后遍历返回的Lookup<TKey, TElement>对象,输出ID以及此ID下的所有名称
public void ToLookUp()
{
//查询语法
Product[] pro = {
new Product{ ID=1, Name="哈哈", Age=45},
new Product{ ID=2,Name="哇哈哈", Age=55},
new Product{ ID=1,Name="嘿嘿", Age=45},
};
var result = pro.ToLookup(
p => p.ID,
p => p.Name
);
foreach (var item in result)
{
Console.WriteLine(item.Key);
foreach (var items in item)
{
Console.WriteLine(items);
}
}
}
输出结果:1
哈哈
嘿嘿
2
哇哈哈
30.Empty:返回一个指定类型的空集合
Demo:
此示例创建一个IEnumerable<int>类型的空集合
public void Empty()
{
var q = Enumerable.Empty<int>();
Console.WriteLine(q == null);
Console.WriteLine(q.Count());
}
输出结果:false 0
31.Join:将两个数据源相联接,根据两个数据源中相等的值进行匹配
Demo:
此示例将产品表与类别表相联接,得到产品名称和与其相对应的类别名称
public void Join()
{
Product[] pro = {
new Product{ ID=1,Name="蛋挞", TID=1},
new Product{ ID=2,Name="冰淇淋", TID=2},
new Product{ ID=1,Name="酱油", TID=3},
new Product{ ID=1,Name="老冰棍", TID=2}
};
Type[] type = {
new Type{ ID=1, TName="甜点"},
new Type{ ID=2, TName="冰点"},
new Type{ ID=3, TName="柴米油盐"}
};
//查询语法
var result = from p in pro
join t in type on p.TID equals t.ID
where p.TID == 1
select p;
foreach (var item in result)
{
Console.WriteLine(item.Name);
}
//方法语法
var list = pro.Join(
type,
p => p.TID,
c => c.ID,
(p, c) => p
).Where(p=>p.TID==1);
}
输出结果:蛋挞