LINQ学习总结
- 获取数据源
- 创建查询
- 方法语法
- 标准查询运算符
- Cast
- GroupBy
- GroupJoin
- Join
- OrderBy
- OrderByDescending
- ThenBy
- ThenByDescending
- Select
- SelectMany
- Where
- Aggregate
- All 是否都满足条件
- Any 是否包含
- Average 平均值
- Concat 组合
- Except 差集
- Intersect 交集
- Union 并集
- Contains 是否包含
- Count 数量
- Distinct 去重
- ElementAt
- ElementAtOrDefault
- Empty 指定类型空值
- First 第一个
- FirstOrDefault
- Last 最后一个
- LastOrDefault
- Max
- Min
- OfType 指定类型筛选元素
- Range
- Repeat
- SequanceEqual 比较元素
- Single 单个特定元素
- SingleOrDefault
- Sum
- Reverse 反转
- Skip
- SkipWhile
- Take
- TakeWhile
- ToArray
- ToList
- ToDictionary
- ToLookup
- 执行方式
获取数据源
语句:from 范围变量 in 数据源
可查询类型(支持IEnumberable或派生接口,如泛型IQueryable 的类型)无需修改或处理就可作为LINQ数据源。
如果源数据不是可查询类型,则LINQ提供程序必须以此方式表示源数据,如下操作。
//LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中
XElement contacts = XElement.Load(@"c:\myContactList.xml");
//LINQ to SQL
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
可以通过使用let子句引入其他范围变量
在一般情况下,编译器可以直接推断范围变量的类型,而若数据源是非泛型IEnumerable集合,必须显式声明范围变量的类型,如下操作。
//arrayList为非泛型的ArrayList集合
var query=from Student s in arrayList;
创建查询
from子句
from子句
```csharp
var lowNums = from num in numbers
where num < 5
select num;
```
复合from子句
```csharp
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };
```
筛选(where子句)
使用where子句,仅返回表达式为true的元素。可以使用“&&”和“||”应用更多的筛选器表达式。
csharp var queryLondonCustomers = from cust in customers where cust.City == "London" && cust.Name == "Devon" select cust;
orderby子句
对返回的数据排序,ascending为顺序,descending为逆序,默认为顺序
```csharp
class OrderbySample1
{
static void Main()
{
// Create a delicious data source.
string[] fruits = { "cherry", "apple", "blueberry" };
// 顺序排序.
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;
}
}
/* Output:
Ascending:
apple
blueberry
cherry
```
///Dictionary例子
public static void Main(string[] args)
{
Dictionary<int, string> dictionary = new Dictionary<int, string> {{1, "cherry"},{3,"apple"},{2,"blueberry"}};
IOrderedEnumerable<KeyValuePair<int, string>> sortAscendingQuery =
from fruit in dictionary
orderby fruit.Key//"ascending" is default
select fruit;
// Solution solution = new Solution();
// int x = solution.MakeStringSorted("cdbea");
foreach (var valuePair in sortAscendingQuery)
{
Console.WriteLine(valuePair.Value);
}
}
/* Output:
cherry
blueberry
apple
group by子句
语句:group item by key
根据指定的键分组
```csharp
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
///Dictionary例子
public static void Main(string[] args)
{
Dictionary<int, string> dictionary = new Dictionary<int, string> {{1, "aa"},{3,"bb"},{2,"aa"}};
var queryCustomersByCity =
from cust in dictionary
group cust by cust.Value;
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (var item in customerGroup)
{
Console.WriteLine(" {0}", item.Key);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Output:
aa
1
2
bb
3
如上操作的结果为列表形式,列表元素带有Key,所有元素根据key来分组。
语句:group item by key into group
使用into可以得到范围变量,能直接引用某个组操作
```csharp
// custQuery is an IEnumerable<IGrouping<string, Customer>>
var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;
```
///Dictionary例子
public static void Main(string[] args)
{
Dictionary<int, string> dictionary = new Dictionary<int, string> {{3,"bb"},{2,"aa"},{1, "aa"}};
var queryCustomersByCity =
from cust in dictionary
group cust by cust.Value into custGroup
orderby custGroup.Key
select custGroup;
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (var item in customerGroup)
{
Console.WriteLine(" {0}", item.Key);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Output:
aa
2
1
bb
3
join子句
语句:join item in itemResource on item.property equals preItem.property
在 LINQ 中,join 子句始终作用于对象集合,而非直接作用于数据库表。
```csharp
//查找所有位置相同的客户和分销商
var innerJoinQuery =
from cust in customers
join dist in distributors on cust.City equals dist.City
select new { CustomerName = cust.Name, DistributorName = dist.Name };
///Dictionary例子
public static void Main(string[] args)
{
Dictionary<int, Customer> customers = new Dictionary<int, Customer>
{
{1, new Customer() {city = "hangzhou", name = "wry"}},
{2, new Customer() {city = "ningbo", name = "wry2"}}
};
Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
{
{1, new Distributor() {city = "hangzhou", name = "wry3"}},
{2, new Distributor() {city = "ningbo", name = "wry4"}}
};
var queryCustomersByCity =
from cust in customers
join distributor in distributors on cust.Value.city equals distributor.Value.city
select new {CustName = cust.Value.name, DistName = distributor.Value.name};
foreach (var item in queryCustomersByCity)
{
Console.WriteLine("{0} {1}",item.CustName,item.DistName);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Output:
wry wry3
wry2 wry4
Press any key to exit
```
select子句
查询表达式必须以 select 子句或 group 子句结尾。 在最简单的情况下,select 子句仅指定范围变量, 这时返回的序列包含与数据源类型相同的元素。此外,select 子句还提供了强大的机制,用于将源数据转换(或投影)为新类型。
```csharp
var query = from cust in Customer
select new {Name = cust.Name, City = cust.City};
///Dictionary例子
public static void Main(string[] args)
{
Dictionary<int, Customer> customers = new Dictionary<int, Customer>
{
{1, new Customer() {city = "hangzhou", name = "wry"}},
{2, new Customer() {city = "ningbo", name = "wry2"}}
};
Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
{
{1, new Distributor() {city = "hangzhou", name = "wry3"}},
{2, new Distributor() {city = "ningbo", name = "wry4"}}
};
var queryCustomersByCity =
from cust in customers
join distributor in distributors on cust.Value.city equals distributor.Value.city
select new {CustName = cust.Value.name, DistName = distributor.Value.name};
foreach (var item in queryCustomersByCity)
{
Console.WriteLine("{0} {1}",item.CustName,item.DistName);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Output:
wry wry3
wry2 wry4
Press any key to exit
```
方法语法
上述的方法皆属于查询语法。查询语法和方法语法在语义上是相同的,但是查询语法更简单且更易于阅读。 某些查询必须表示为方法调用(比如.Count()的查询)。
```csharp
//查询语法:
IEnumerable<int> numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;
//方法语法:
IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
///Dictionary例子
//查询语法:
Dictionary<int, int> dictionary = new Dictionary<int, int>();
dictionary.Add(1,7);
dictionary.Add(2,2);
dictionary.Add(3,8);
dictionary.Add(4,3);
dictionary.Add(5,4);
IOrderedEnumerable<KeyValuePair<int, int>> numQuery1 =
from num in dictionary
where num.Value % 2 == 0
orderby num.Value
select num;
foreach (var item in numQuery1)
{
Console.WriteLine("{0}",item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
2
5
3
//方法语法
Dictionary<int, int> dictionary = new Dictionary<int, int>();
dictionary.Add(1,7);
dictionary.Add(2,2);
dictionary.Add(3,8);
dictionary.Add(4,3);
dictionary.Add(5,4);
IOrderedEnumerable<KeyValuePair<int, int>> numQuery2 = dictionary.Where(num => num.Value % 2 == 0)
.OrderBy(num => num.Value);
foreach (var item in numQuery2)
{
Console.WriteLine("{0}",item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
2
5
3
标准查询运算符
Cast
执行方式:流式处理
将 IEnumerable 的元素强制转换为指定的类型。
```csharp
IEnumerable<string> query =
fruits.Cast<string>().OrderBy(fruit => fruit).Select(fruit => fruit);
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1,"aa");
dictionary.Add(2,"cc");
dictionary.Add(3,"bb");
dictionary.Add(4,"ff");
dictionary.Add(5,"ee");
var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value);
foreach (var item in numQuery2)
{
Console.WriteLine(item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
1
3
2
5
4
Press any key to exit
```
GroupBy
执行方式:非流式处理
根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的函数对每个组的元素进行投影。
```csharp
public static void GroupByEx4()
{
// Create a list of pets.
List petsList =
new List{ new Pet { Name=“Barley”, Age=8.3 },
new Pet { Name=“Boots”, Age=4.9 },
new Pet { Name=“Whiskers”, Age=1.5 },
new Pet { Name=“Daisy”, Age=4.3 } };
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age), //key
pet => pet.Age, //element
(baseAge, ages) => new
{
Key = baseAge,
Count = ages.Count(),
Min = ages.Min(),
Max = ages.Max()
}); //结果集(key,IEnumerable groupList)
// Iterate over each anonymous type.
foreach (var result in query)
{
Console.WriteLine("\nAge group: " + result.Key);
Console.WriteLine("Number of pets in this age group: " + result.Count);
Console.WriteLine("Minimum age: " + result.Min);
Console.WriteLine("Maximum age: " + result.Max);
}
/* This code produces the following output:
Age group: 8
Number of pets in this age group: 1
Minimum age: 8.3
Maximum age: 8.3
Age group: 4
Number of pets in this age group: 2
Minimum age: 4.3
Maximum age: 4.9
Age group: 1
Number of pets in this age group: 1
Minimum age: 1.5
Maximum age: 1.5
*/
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1,"aa");
dictionary.Add(2,"cc");
dictionary.Add(3,"aa");
dictionary.Add(4,"cc");
dictionary.Add(5,"ee");
var numQuery2 = dictionary.GroupBy(item => item.Value);
foreach (var group in numQuery2)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}",item.Key);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
aa
1
3
cc
2
4
ee
5
Press any key to exit
```
GroupJoin
执行方式:流式处理和非流式处理
基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用指定的 IEqualityComparer 对键进行比较。
```csharp
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<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };
var query = //返回IEnumerable<result>
people.GroupJoin(pets, //要联接的序列
person => person, //第一个序列中提取联接键,按键分组
pet => pet.Owner, //第二个序列中提取联接键
(person, petCollection) => //创建结果元素
new
{
OwnerName = person.Name,
Pets = petCollection.Select(pet => pet.Name)
});
foreach (var obj in query)
{
// Output the owner's name.
Console.WriteLine("{0}:", obj.OwnerName);
// Output each of the owner's pet's names.
foreach (string pet in obj.Pets)
{
Console.WriteLine(" {0}", pet);
}
}
/*
This code produces the following output:
Hedlund, Magnus:
Daisy
Adams, Terry:
Barley
Boots
Weiss, Charlotte:
Whiskers
*/
///Dictionary例子
Dictionary<int, Customer> customers = new Dictionary<int, Customer>
{
{1, new Customer() {city = "hangzhou", name = "wry"}},
{2, new Customer() {city = "ningbo", name = "wry2"}}
};
Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
{
{1, new Distributor() {city = "hangzhou", name = "wry3"}},
{2, new Distributor() {city = "ningbo", name = "wry4"}}
};
var query = customers.GroupJoin(distributors,
custCity => custCity.Value.city,
distCity => distCity.Value.city,
(custName, collection) =>
new
{
custN = custName.Value.name,
distN = collection.Select(dist => dist.Value.name)
}
);
foreach (var group in query)
{
Console.WriteLine(group.custN);
foreach (var item in group.distN)
{
Console.WriteLine(" {0}",item);
}
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
wry
wry3
wry2
wry4
Press any key to exit
```
Join
执行方式:流式处理与非流式处理
基于匹配键对两个序列的元素进行关联。
```csharp
var query =
people.Join(pets, //要联接的序列
person => person, //第一个序列中提取联接键
pet => pet.Owner, //第二个序列中提取联接键
(person, pet) => //创建结果元素
new { OwnerName = person.Name, Pet = pet.Name });
///Dictionary例子
Dictionary<int, Customer> customers = new Dictionary<int, Customer>
{
{1, new Customer() {city = "hangzhou", name = "wry"}},
{2, new Customer() {city = "ningbo", name = "wry2"}}
};
Dictionary<int,Distributor> distributors = new Dictionary<int, Distributor>
{
{1, new Distributor() {city = "hangzhou", name = "wry3"}},
{2, new Distributor() {city = "ningbo", name = "wry4"}}
};
var query = customers.Join(distributors,
custCity => custCity.Value.city,
distCity => distCity.Value.city,
(custName, distName) =>
new
{
custN = custName.Value.name,
distN = distName.Value.name
}
);
foreach (var group in query)
{
Console.WriteLine("{0} {1}",group.custN,group.distN);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
wry wry3
wry2 wry4
Press any key to exit
```
OrderBy
执行方式:非流式处理
根据键按升序对序列的元素进行排序。
```csharp
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1,"aa");
dictionary.Add(2,"cc");
dictionary.Add(3,"bb");
dictionary.Add(4,"ff");
dictionary.Add(5,"ee");
var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value);
foreach (var item in numQuery2)
{
Console.WriteLine(item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
1
3
2
5
4
Press any key to exit
```
OrderByDescending
执行方式:非流式处理
根据键按降序对序列的元素进行排序。
```csharp
IEnumerable<Pet> query = pets.OrderByDescending(pet => pet.Age);
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1,"aa");
dictionary.Add(2,"cc");
dictionary.Add(3,"bb");
dictionary.Add(4,"ff");
dictionary.Add(5,"ee");
var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderByDescending(num => num.Value);
foreach (var item in numQuery2)
{
Console.WriteLine(item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
4
5
2
3
1
Press any key to exit
```
ThenBy
执行方式:非流式处理
根据某个键按升序对序列中的元素执行后续排序。
```csharp
IEnumerable<string> query =
fruits.OrderBy(fruit => fruit.Length).ThenBy(fruit => fruit);
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(2,"aa");
dictionary.Add(4,"aa");
dictionary.Add(1,"aa");
dictionary.Add(3,"bb");
dictionary.Add(5,"bb");
var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value).ThenBy(num=>num.Key);
foreach (var item in numQuery2)
{
Console.WriteLine(item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
1
2
4
3
5
Press any key to exit
```
ThenByDescending
执行方式:非流式处理
根据某个键按降序对序列中的元素执行后续排序。
IEnumerable<string> query =
fruits
.OrderBy(fruit => fruit.Length)
.ThenByDescending(fruit => fruit, new CaseInsensitiveComparer());
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(2,"aa");
dictionary.Add(4,"aa");
dictionary.Add(1,"aa");
dictionary.Add(3,"bb");
dictionary.Add(5,"bb");
var numQuery2 = dictionary.Cast<KeyValuePair<int,string>>().OrderBy(num => num.Value).ThenByDescending(num=>num.Key);
foreach (var item in numQuery2)
{
Console.WriteLine(item.Key);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
4
2
1
5
3
Press any key to exit
Select
执行方式:流式处理
通过合并元素的索引,将序列的每个元素投影到新窗体中。
```csharp
var query =
fruits.Select((fruit, index) =>
new { index, str = fruit.Substring(0, index) });
///Dictionary例子
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(2,"aa");
dictionary.Add(4,"aa");
dictionary.Add(1,"aa");
dictionary.Add(3,"bb");
dictionary.Add(5,"bb");
var numQuery2 = dictionary.Select(num => new {num.Key, Name = num.Value.Substring(0, 1)});
foreach (var item in numQuery2)
{
Console.WriteLine("{0} {1}",item.Key,item.Name);
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Output:
2 a
4 a
1 a
3 b
5 b
Press any key to exit
```
SelectMany
执行方式:流式处理
将序列的每个元素投影到 IEnumerable,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。
class PetOwner
{
public string Name { get; set; }
public List Pets { get; set; }
}
public static void SelectManyEx3()
{
PetOwner[] petOwners =
{ new PetOwner { Name="Higa",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines",
Pets = new List<string>{ "Dusty" } } };
// Project the pet owner's name and the pet's name.
var query =
petOwners
.SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName })
.Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
.Select(ownerAndPet =>
new
{
Owner = ownerAndPet.petOwner.Name,
Pet = ownerAndPet.petName
}
);
// Print the results.
foreach (var obj in query)
{
Console.WriteLine(obj);
}
}
// This code produces the following output:
//
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam}
// {Owner=Ashkenazi, Pet=Sugar}
// {Owner=Price, Pet=Scratches}
///Dictionary例子
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(1, "aaa");
dic.Add(2, "bbb");
Dictionary<int, string> dic2 = new Dictionary<int, string>();
dic2.Add(3, "ccc");
dic2.Add(4, "ddd");
var dictionaries = new List< Dictionary<int,string> >(){ dic,dic2 }.SelectMany(dict =>dict).ToDictionary(pair => pair.Key, pair => pair.Value);
// Print the results.
foreach (var obj in dictionaries)
{
Console.WriteLine(obj);
}
Output:
[1, aaa]
[2, bbb]
[3, ccc]
[4, ddd]
Where
执行方式:流式处理
根据条件筛值
```csharp
IEnumerable<string> query = fruits.Where(fruit => fruit.Length < 6);
///Dictionary例子
Dictionary<int, string> dic = new Dictionary<int, string>();
dic.Add(1, "aaa");
dic.Add(2, "bbb");
var res=dic.Where(val => val.Key == 1).Select(val => val.Value);
// Print the results.
foreach (var obj in res)
{
Console.WriteLine(obj);
}
Output:
aaa
```
Aggregate
执行方式:立即执行
将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。
```csharp
string[] fruits = { “apple”, “mango”, “orange”, “passionfruit”, “grape” };
// Determine whether any string in the array is longer than "banana".
string longestName =
fruits.Aggregate("banana", //种子
(longest, next) => //Func
next.Length > longest.Length ? next : longest,
// Return the final result as an upper case string.
fruit => fruit.ToUpper()); //结果
// This code produces the following output:
//
// The fruit with the longest name is PASSIONFRUIT.
///Dictionary例子
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{1, "apple"},
{2, "mango"},
{3, "orange"},
{4, "passionfruit"},
{5, "grape"}
};
// Determine whether any string in the array is longer than "banana".
string longestName =
fruits.Aggregate("banana", //种子
(longest, next) => //Func
next.Value.Length > longest.Length ? next.Value : longest,
// Return the final result as an upper case string.
fruit => fruit.ToUpper()); //结果
Console.WriteLine(longestName);
Output:
PASSIONFRUIT
```
All 是否都满足条件
执行方式:立即执行
确定序列中的所有元素是否都满足条件。
```csharp
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void AllEx()
{
// Create an array of Pets.
Pet[] pets = { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=6 } };
// Determine whether all pet names
// in the array start with 'B'.
bool allStartWithB = pets.All(pet =>
pet.Name.StartsWith("B"));
Console.WriteLine(
"{0} pet names start with 'B'.",
allStartWithB ? "All" : "Not all");
}
// This code produces the following output:
//
// Not all pet names start with 'B'.
///Dictionary例子
Dictionary<int,Pet> pets = new Dictionary<int, Pet> {{1, new Pet { Name="Barley", Age=10 }},
{2,new Pet {Name = "Boots", Age = 4}},
{3,new Pet {Name = "Whiskers", Age = 6}} };
// Determine whether all pet names
// in the array start with 'B'.
bool allStartWithB = pets.All(pet =>
pet.Value.Name.StartsWith("B"));
Console.WriteLine(
"{0} pet names start with 'B'.",
allStartWithB ? "All" : "Not all");
Output:
Not all pet names start with 'B'.
Any 是否包含
执行方式:立即执行
确定序列中是否包含元素或存在元素满足指定条件。
```csharp
//判断序列是否包含任何元素
List<int> numbers = new List<int> { 1, 2 };
bool hasElements = numbers.Any();
Console.WriteLine("The list {0} empty.",
hasElements ? "is not" : "is");
// This code produces the following output:
//
// The list is not empty.
bool unvaccinated =//判断是否有元素满足以下条件
pets.Any(p => p.Age > 1 && p.Vaccinated == false);
///dictionary例子
Dictionary<int,Pet> pets = new Dictionary<int, Pet> {{1, new Pet { Name="Barley", Age=10 }},
{2,new Pet {Name = "Boots", Age = 4}},
{3,new Pet {Name = "Whiskers", Age = 6}} };
// Determine whether all pet names
// in the array start with 'B'.
bool allStartWithB = pets.Any(p => p.Value.Age > 5);
Console.WriteLine(
"{0} pet whose age is beyond 5 .",
allStartWithB ? "Have" : "Dont have");
Output:
Have pet whose age is beyond 5 .
```
Average 平均值
执行方式:立即执行
计算数值序列的平均值。
```csharp
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };
double average = fruits.Average(s => s.Length);
Console.WriteLine("The average string length is {0}.", average);
///Dictionary例子
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{1, "apple"},
{2, "mango"},
{3, "orange"},
{4, "passionfruit"},
{5, "grape"}
};
double average = fruits.Average(s => s.Value.Length);
Console.WriteLine("The average string length is {0}.", average);
Output:
The average string length is 6.6.
```
Concat 组合
执行方式:流式处理
组合多个输入。
```csharp
var peopleInSeattle = (from student in students
where student.City == “Seattle”
select student.Last)
.Concat(from teacher in teachers
where teacher.City == “Seattle”
select teacher.Last);
///Dictionary例子
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{1, "apple"},
{2, "mango"},
{3, "orange"},
{4, "passionfruit"},
{5, "grape"}
};
Dictionary<int,Pet> pets = new Dictionary<int, Pet> {{1, new Pet { Name="Barley", Age=10 }},
{2,new Pet {Name = "Boots", Age = 4}},
{3,new Pet {Name = "Whiskers", Age = 6}} };
var result = (from fruit in fruits
where fruit.Key > 2
select fruit.Value).Concat(from pet in pets
where pet.Key > 1
select pet.Value.Name);
foreach (var re in result)
{
Console.WriteLine(" {0}.", re);
}
Output:
orange.
passionfruit.
grape.
Boots.
Whiskers.
```
Except 差集
执行方式:流式处理和非流式处理
生成两个序列的差集。
double[] numbers1 = { 2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 };
IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
foreach (double number in onlyInFirstSet)
Console.WriteLine(number);
/*
This code produces the following output:
2
2.1
2.3
2.4
2.5
*/
///Dictionary例子
Dictionary<int, string> fruits = new Dictionary<int, string>
{
{1, "apple"},
{2, "mango"},
{3, "orange"},
{4, "passionfruit"},
{5, "grape"}
};
Dictionary<int, string> fruits2 = new Dictionary<int, string>
{
{1, "apple"}
};
var onlyInFirstSet = fruits.Except(fruits2);
foreach (var number in onlyInFirstSet)
{
Console.WriteLine(number.Value);
}
Output:
mango
orange
passionfruit
grape
Intersect 交集
执行方式:流式处理与非流式处理
生成两个序列的交集。
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}
// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Product x, Product y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(Product product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;
//Get hash code for the Name field if it is not null.
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();
//Get hash code for the Code field.
int hashProductCode = product.Code.GetHashCode();
//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}
Product[] store1 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };
Product[] store2 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "lemon", Code = 12 } };
IEnumerable<Product> duplicates =
store1.Intersect(store2, new ProductComparer());
foreach (var product in duplicates)
Console.WriteLine(product.Name + " " + product.Code);
/*
This code produces the following output:
apple 9
*/
///Dictionary例子
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}
// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<KeyValuePair<int,Product>>
{
public bool Equals(KeyValuePair<int, Product> x, KeyValuePair<int, Product> y)
{
return x.Value.Code == y.Value.Code&&x.Value.Name.Equals(y.Value.Name)&&x.Key==y.Key;
}
public int GetHashCode(KeyValuePair<int, Product> obj)
{
if (Object.ReferenceEquals(obj,null))
{
return 0;
}
int hashProjectName = obj.Value.Name == null ? 0 : obj.Value.Name.GetHashCode();
int hashProjectCode = obj.Value.Code == null ? 0 : obj.Value.Code.GetHashCode();
int hashkey = obj.Key.GetHashCode();
return hashkey ^ hashProjectCode ^ hashProjectName;
}
}
Dictionary<int,Product> store1 = new Dictionary<int, Product>{
{1, new Product { Name = "apple", Code = 9 }},
{2,new Product {Name = "orange", Code = 4}}
};
Dictionary<int,Product> store2 = new Dictionary<int, Product>{
{1,new Product {Name = "apple", Code = 9}},
{2,new Product {Name = "lemon", Code = 12}} };
var duplicates =
store1.Intersect(store2,new ProductComparer());
foreach (var product in duplicates)
Console.WriteLine(product.Value.Name + " " + product.Value.Code);
Output:
apple 9
Union 并集
执行方式:流式处理
通过使用默认的相等比较器,生成两个序列的并集,返回一个包含两个输入序列中的非重复元素的 IEnumerable。
int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 };
int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 };
IEnumerable<int> union = ints1.Union(ints2);
foreach (int num in union)
{
Console.Write("{0} ", num);
}
/*
This code produces the following output:
5 3 9 7 8 6 4 1 0
*/
///Dictionary例子
Dictionary<int,int> ints1 = new Dictionary<int, int>{{1,5}, {4,3}, {3,9}};
Dictionary<int,int> ints2 = new Dictionary<int, int>{{1,8}, {2,3}, {3,6}};
IEnumerable<KeyValuePair<int, int>> union = ints1.Union(ints2);
foreach (var num in union)
{
Console.WriteLine("{0} {1}", num.Key,num.Value);
}
Output:///键值相同才能去重
1 5
4 3
3 9
1 8
2 3
3 6
如果要比较某种自定义数据类型的对象序列,则必须 IEquatable 在 helper 类中实现泛型接口。 下面的代码示例演示如何在自定义数据类型中实现此接口并重写 GetHashCode 和 Equals 方法。
```csharp
public class ProductA: IEquatable<ProductA>
{
public string Name { get; set; }
public int Code { get; set; }
public bool Equals(ProductA other)
{
if (other is null)
return false;
return this.Name == other.Name && this.Code == other.Code;
}
public override bool Equals(object obj) => Equals(obj as ProductA);
public override int GetHashCode() => (Name, Code).GetHashCode();
}
```
```csharp
ProductA[] store1 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 } };
ProductA[] store2 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "lemon", Code = 12 } };
//Get the products from the both arrays
//excluding duplicates.
IEnumerable<ProductA> union =
store1.Union(store2);
foreach (var product in union)
Console.WriteLine(product.Name + " " + product.Code);
/*
This code produces the following output:
apple 9
orange 4
lemon 12
*/
```
Contains 是否包含
执行方式:立即执行
确定序列是否包含指定的元素。
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };
string fruit = "mango";
bool hasMango = fruits.Contains(fruit);
///Dictionary例子
Dictionary<int,int> ints1 = new Dictionary<int, int>{{1,5}, {2,3}, {3,9}};
int anum = 3;
bool hasItem = ints1.ContainsValue(anum);
Console.WriteLine("{0}",hasItem);
Output:
True
Count 数量
执行方式:立即执行
返回序列中的元素数量。
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };
try
{
int numberOfFruits = fruits.Count();
Console.WriteLine(
"There are {0} fruits in the collection.",
numberOfFruits);
}
catch (OverflowException)
{
Console.WriteLine("The count is too large to store as an Int32.");
Console.WriteLine("Try using the LongCount() method instead.");
}
// This code produces the following output:
//
// There are 6 fruits in the collection.
///Dictionary例子
Dictionary<int,int> ints1 = new Dictionary<int, int>{{1,5}, {2,3}, {3,9}};
int hasItem = ints1.Count;
Console.WriteLine("{0}",hasItem);
Output:
3
Distinct 去重
执行方式:流式处理
返回序列中的非重复元素。
List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };
IEnumerable<int> distinctAges = ages.Distinct();
Console.WriteLine("Distinct ages:");
foreach (int age in distinctAges)
{
Console.WriteLine(age);
}
/*
This code produces the following output:
Distinct ages:
21
46
55
17
*/
ElementAt
执行方式:立即执行
返回序列中指定索引处的元素。
```csharp
string[] names =
{ "Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };
Random random = new Random(DateTime.Now.Millisecond);
string name = names.ElementAt(random.Next(0, names.Length));
Console.WriteLine("The name chosen at random is '{0}'.", name);
/*
This code produces output similar to the following:
The name chosen at random is 'Ito, Shu'.
*/
///Dictionary例子
Dictionary<int,int> ints1 = new Dictionary<int, int>{{1,5}, {2,3}, {3,9},{4,3}};
var item=ints1.ElementAt(1);
Console.WriteLine("{0}",item.Value);
Output:
3
```
ElementAtOrDefault
执行方式:立即执行
返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。
```csharp
string[] names =
{ "Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };
int index = 20;
string name = names.ElementAtOrDefault(index);
Console.WriteLine(
"The name chosen at index {0} is '{1}'.",
index,
String.IsNullOrEmpty(name) ? "<no name at this index>" : name);
/*
This code produces the following output:
The name chosen at index 20 is '<no name at this index>'.
*/
///DIctionary例子
Dictionary<int,int> ints1 = new Dictionary<int, int>{{1,5}, {2,3}, {3,9},{4,3}};
var item=ints1.ElementAtOrDefault(5);
Console.WriteLine("{0}",item.Value);
Output:
0
```
Empty 指定类型空值
执行方式:立即执行
返回具有指定类型参数的空 IEnumerable。
string[] names1 = { "Hartono, Tommy" };
string[] names2 = { "Adams, Terry", "Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };
string[] names3 = { "Solanki, Ajay", "Hoeing, Helge",
"Andersen, Henriette Thaulow",
"Potra, Cristina", "Iallo, Lucio" };
List<string[]> namesList =
new List<string[]> { names1, names2, names3 };
// Only include arrays that have four or more elements
IEnumerable<string> allNames =
namesList.Aggregate(Enumerable.Empty<string>(),
(current, next) => next.Length > 3 ? current.Union(next) : current);
foreach (string name in allNames)
{
Console.WriteLine(name);
}
/*
This code produces the following output:
Adams, Terry
Andersen, Henriette Thaulow
Hedlund, Magnus
Ito, Shu
Solanki, Ajay
Hoeing, Helge
Potra, Cristina
Iallo, Lucio
*/
First 第一个
执行方式:立即执行。
返回序列中的第一个元素。
```csharp
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 435, 67, 12, 19 };
int first = numbers.First();
Console.WriteLine(first);
/*
This code produces the following output:
9
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.First();
Console.WriteLine("{0} {1}",item.Key,item.Value);
Output:
1 5
```
FirstOrDefault
执行方式:立即执行。
返回序列中的第一个元素;如果未找到该元素,则返回默认值。
```csharp
string[] names = { "Hartono, Tommy", "Adams, Terry",
"Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };
string firstLongName = names.FirstOrDefault(name => name.Length > 20);
Console.WriteLine("The first long name is '{0}'.", firstLongName);
string firstVeryLongName = names.FirstOrDefault(name => name.Length > 30);
Console.WriteLine(
"There is {0} name longer than 30 characters.",
string.IsNullOrEmpty(firstVeryLongName) ? "not a" : "a");
/*
This code produces the following output:
The first long name is 'Andersen, Henriette Thaulow'.
There is not a name longer than 30 characters.
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.FirstOrDefault(num=>num.Value<3);
Console.WriteLine("{0} {1}",item.Key,item.Value);
Output:
0 0
```
Last 最后一个
执行方式:立即执行
返回序列的最后一个元素。
```csharp
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 67, 12, 19 };
int last = numbers.Last();
Console.WriteLine(last);
/*
This code produces the following output:
19
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.Last(num=>num.Value>3);
Console.WriteLine("{0} {1}",item.Key,item.Value);
Output:
3 9
```
LastOrDefault
执行方式:立即执行
返回序列中的最后一个元素;如果未找到该元素,则返回默认值。
```csharp
string[] fruits = { };
string last = fruits.LastOrDefault();
Console.WriteLine(
String.IsNullOrEmpty(last) ? "<string is null or empty>" : last);
/*
This code produces the following output:
<string is null or empty>
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.LastOrDefault(num=>num.Value<3);
Console.WriteLine("{0} {1}",item.Key,item.Value);
Output:
0 0
```
Max
执行方式:立即执行
返回值序列中的最大值。
List<long> longs = new List<long> { 4294967296L, 466855135L, 81125L };
long max = longs.Max();
Console.WriteLine("The largest number is {0}.", max);
/*
This code produces the following output:
The largest number is 4294967296.
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.Max(val=>val.Value);
Console.WriteLine("{0} ",item);
Output:
9
```
Min
执行方式:立即执行
返回值序列中的最小值。
```csharp
int?[] grades = { 78, 92, null, 99, 37, 81 };
int? min = grades.Min();
Console.WriteLine("The lowest grade is {0}.", min);
/*
This code produces the following output:
The lowest grade is 37.
*/
///Dictionary例子
Dictionary<int, int> ints1 = new Dictionary<int, int> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var item = ints1.Min(val=>val.Value);
Console.WriteLine("{0} ",item);
Output:
3
```
OfType 指定类型筛选元素
执行方式:流式处理
根据指定类型筛选 IEnumerable 的元素。
System.Collections.ArrayList fruits = new System.Collections.ArrayList(4);
fruits.Add("Mango");
fruits.Add("Orange");
fruits.Add("Apple");
fruits.Add(3.0);
fruits.Add("Banana");
// Apply OfType() to the ArrayList.
IEnumerable<string> query1 = fruits.OfType<string>();
Console.WriteLine("Elements of type 'string' are:");
foreach (string fruit in query1)
{
Console.WriteLine(fruit);
}
// The following query shows that the standard query operators such as
// Where() can be applied to the ArrayList type after calling OfType().
IEnumerable<string> query2 =
fruits.OfType<string>().Where(fruit => fruit.ToLower().Contains("n"));
Console.WriteLine("\nThe following strings contain 'n':");
foreach (string fruit in query2)
{
Console.WriteLine(fruit);
}
// This code produces the following output:
//
// Elements of type 'string' are:
// Mango
// Orange
// Apple
// Banana
//
// The following strings contain 'n':
// Mango
// Orange
// Banana
Range
执行方式:流式处理
生成指定范围内的整数的序列。Range (int start, int count)。
start Int32
序列中第一个整数的值。
count Int32
要生成的顺序整数的数目。
```csharp
IEnumerable<int> squares = Enumerable.Range(1, 10).Select(x => x * x);
foreach (int num in squares)
{
Console.WriteLine(num);
}
/*
This code produces the following output:
1
4
9
16
25
36
49
64
81
100
*/
```
Repeat
执行方式:流式处理
生成包含一个重复值的序列。
IEnumerable<string> strings =
Enumerable.Repeat("I like programming.", 15);
foreach (String str in strings)
{
Console.WriteLine(str);
}
/*
This code produces the following output:
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
*/
SequanceEqual 比较元素
执行方式:立即执行
通过使用相应类型的默认相等比较器对序列的元素进行比较,若引用的是对象,则当确定两个序列是对同一个对象的引用时才返回true。
```csharp
/相等的例子
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void SequenceEqualEx1()
{
Pet pet1 = new Pet { Name = "Turbo", Age = 2 };
Pet pet2 = new Pet { Name = "Peanut", Age = 8 };
// Create two lists of pets.
List<Pet> pets1 = new List<Pet> { pet1, pet2 };
List<Pet> pets2 = new List<Pet> { pet1, pet2 };
bool equal = pets1.SequenceEqual(pets2);
Console.WriteLine(
"The lists {0} equal.",
equal ? "are" : "are not");
}
/*
This code produces the following output:
The lists are equal.
*/
//应用对象不同,但值相同,判断仍为不相等
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void SequenceEqualEx2()
{
Pet pet1 = new Pet() { Name = "Turbo", Age = 2 };
Pet pet2 = new Pet() { Name = "Peanut", Age = 8 };
// Create two lists of pets.
List<Pet> pets1 = new List<Pet> { pet1, pet2 };
List<Pet> pets2 =
new List<Pet> { new Pet { Name = "Turbo", Age = 2 },
new Pet { Name = "Peanut", Age = 8 } };
bool equal = pets1.SequenceEqual(pets2);
Console.WriteLine("The lists {0} equal.", equal ? "are" : "are not");
}
/*
This code produces the following output:
The lists are not equal.
*/
///Dictionary例子
Dictionary<int, object> ints1 = new Dictionary<int, object> {{1, 5}, {2, 3}, {3, 9}, {4, 3},{5,"apple"}};
Dictionary<int, object> ints2 = new Dictionary<int, object> {{1, 5}, {2, 3}, {3, 9}, {4, 3},{5,"apple"}};
var items=ints1.OfType<KeyValuePair<int, string>>();
bool isequal=ints1.SequenceEqual(ints2);
Console.WriteLine(isequal);
Output:
True
```
Single 单个特定元素
执行方式:立即执行
返回序列中的单个特定元素。如果有多个这样的元素存在,则会引发异常。如果该序列并非恰好包含一个元素,则会引发异常。
```csharp
string[] fruits = { "apple", "banana", "mango",
"orange", "passionfruit", "grape" };
string fruit1 = fruits.Single(fruit => fruit.Length > 10);
Console.WriteLine(fruit1);
/*
This code produces the following output:
passionfruit
*/
///Dictionary例子
Dictionary<int, object> ints1 = new Dictionary<int, object> {{5,"apple"}};
var isequal=ints1.Single();
Console.WriteLine(isequal.Value);
Output:
apple
```
SingleOrDefault
执行方式:立即执行
返回序列中的单个特定元素;如果未找到该元素,则返回默认值。如果该序列为空,则返回默认值;如果该序列包含多个元素,此方法将引发异常。
```csharp
string[] fruits2 = { };
string fruit2 = fruits2.SingleOrDefault();
Console.WriteLine(
String.IsNullOrEmpty(fruit2) ? "No such string!" : fruit2);
/*
This code produces the following output:
No such string!
*/
///Dictionary例子
Dictionary<int, object> ints1 = new Dictionary<int, object>();
var isequal=ints1.SingleOrDefault();
Console.WriteLine(isequal.Value);
Output:
```
Sum
执行方式:立即执行
要计算其总和的可以为 null 的 Single 值序列。
float?[] points = { null, 0, 92.83F, null, 100.0F, 37.46F, 81.1F };
float? sum = points.Sum();
Console.WriteLine("Total points earned: {0}", sum);
/*
This code produces the following output:
Total points earned: 311.39
*/
Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3},{5,null}};
var isequal=ints2.Sum(num=>num.Value);
Console.WriteLine(isequal);
Output:
20
Reverse 反转
执行方式:非流式处理
char[] apple = { 'a', 'p', 'p', 'l', 'e' };
char[] reversed = apple.Reverse().ToArray();
foreach (char chr in reversed)
{
Console.Write(chr + " ");
}
Console.WriteLine();
/*
This code produces the following output:
e l p p a
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal=ints2.Reverse();
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} {1}",valuePair.Key,valuePair.Value);
}
Output:
4 3
3 9
2 3
1 5
Skip
执行方式:流式处理
跳过序列中指定数量的元素,然后返回剩余的元素。
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };
IEnumerable<int> lowerGrades =
grades.OrderByDescending(g => g).Skip(3);
Console.WriteLine("All grades except the top three are:");
foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
}
/*
This code produces the following output:
All grades except the top three are:
82
70
59
56
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal=ints2.Skip(1);
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} {1}",valuePair.Key,valuePair.Value);
}
Output:
2 3
3 9
4 3
SkipWhile
执行方式:流式处理
如果指定的条件为 true,则跳过序列中的元素,直到元素不满足条件则返回剩余的全部元素,不管之后的元素是否满足条件。
```csharp
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };
IEnumerable<int> lowerGrades =
grades
.OrderByDescending(grade => grade)
.SkipWhile(grade => grade >= 80);
Console.WriteLine("All grades below 80:");
foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
}
/*
This code produces the following output:
All grades below 80:
70
59
56
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal=ints2.OrderBy(item=>item.Value).SkipWhile(item=>item.Value<4);
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} {1}",valuePair.Key,valuePair.Value);
}
Output:
1 5
3 9
```
Take
执行方式:流式处理
从序列的开头返回指定数量的相邻元素。
```
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };
IEnumerable<inttopThreeGrades =
grades.OrderByDescending(grade =grade).Take(3);
Console.WriteLine("The top three grades are:");
foreach (int grade in topThreeGrades)
{
Console.WriteLine(grade);
}
/*
This code produces the following output:
The top three grades are:
98
92
85
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal = ints2.Take(2);
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} {1}",valuePair.Key,valuePair.Value);
}
Output:
1 5
2 3
```
TakeWhile
执行方式:流式处理
如果指定的条件为 true,则返回序列中的元素,若遇到不满足条件的元素,则跳过剩余的全部元素。
string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" };
IEnumerable<string> query =
fruits.TakeWhile(fruit => String.Compare("orange", fruit, true) != 0);
foreach (string fruit in query)
{
Console.WriteLine(fruit);
}
/*
This code produces the following output:
apple
banana
mango
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal = ints2.TakeWhile(item=>item.Value>4);
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} {1}",valuePair.Key,valuePair.Value);
}
Output:
1 5
ToArray
执行方式:立即执行
返回一个包含输入序列中的元素的数组。
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
}
public static void ToArrayEx1()
{
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard", Weight = 25.2 },
new Package { Company = "Lucerne Publishing", Weight = 18.7 },
new Package { Company = "Wingtip Toys", Weight = 6.0 },
new Package { Company = "Adventure Works", Weight = 33.8 } };
string[] companies = packages.Select(pkg => pkg.Company).ToArray();
foreach (string company in companies)
{
Console.WriteLine(company);
}
}
/*
This code produces the following output:
Coho Vineyard
Lucerne Publishing
Wingtip Toys
Adventure Works
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal = ints2.Select(item =>item.Value).ToArray();
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} ",valuePair);
}
output:
5
3
9
3
ToList
执行方式:立即执行
返回一个包含输入序列中的元素的 List。
```csharp
string[] fruits = { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" };
List<int> lengths = fruits.Select(fruit => fruit.Length).ToList();
foreach (int length in lengths)
{
Console.WriteLine(length);
}
/*
This code produces the following output:
5
12
6
5
6
9
5
10
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal = ints2.Select(item =>item.Value).ToList();
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} ",valuePair);
}
output:
5
3
9
3
```
ToDictionary
执行方式:立即执行
根据指定的键选择器和元素选择器函数,从 IEnumerable 创建一个 Dictionary<TKey,TValue>。
```csharp
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
public long TrackingNumber { get; set; }
}
public static void ToDictionaryEx1()
{
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard", Weight = 25.2, TrackingNumber = 89453312L },
new Package { Company = "Lucerne Publishing", Weight = 18.7, TrackingNumber = 89112755L },
new Package { Company = "Wingtip Toys", Weight = 6.0, TrackingNumber = 299456122L },
new Package { Company = "Adventure Works", Weight = 33.8, TrackingNumber = 4665518773L } };
// Create a Dictionary of Package objects,
// using TrackingNumber as the key.
Dictionary<long, Package> dictionary =
packages.ToDictionary(p => p.TrackingNumber);
foreach (KeyValuePair<long, Package> kvp in dictionary)
{
Console.WriteLine(
"Key {0}: {1}, {2} pounds",
kvp.Key,
kvp.Value.Company,
kvp.Value.Weight);
}
}
/*
This code produces the following output:
Key 89453312: Coho Vineyard, 25.2 pounds
Key 89112755: Lucerne Publishing, 18.7 pounds
Key 299456122: Wingtip Toys, 6 pounds
Key 4665518773: Adventure Works, 33.8 pounds
*/
```
ToLookup
执行方式:立即执行
从 IEnumerable 生成一个泛型 Lookup<TKey,TElement>。
```csharp
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
public long TrackingNumber { get; set; }
}
public static void ToLookupEx1()
{
// Create a list of Packages.
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard",
Weight = 25.2, TrackingNumber = 89453312L },
new Package { Company = "Lucerne Publishing",
Weight = 18.7, TrackingNumber = 89112755L },
new Package { Company = "Wingtip Toys",
Weight = 6.0, TrackingNumber = 299456122L },
new Package { Company = "Contoso Pharmaceuticals",
Weight = 9.3, TrackingNumber = 670053128L },
new Package { Company = "Wide World Importers",
Weight = 33.8, TrackingNumber = 4665518773L } };
// Create a Lookup to organize the packages.
// Use the first character of Company as the key value.
// Select Company appended to TrackingNumber
// as the element values of the Lookup.
ILookup<char, string> lookup =
packages
.ToLookup(p => Convert.ToChar(p.Company.Substring(0, 1)),
p => p.Company + " " + p.TrackingNumber);
// Iterate through each IGrouping in the Lookup.
foreach (IGrouping<char, string> packageGroup in lookup)
{
// Print the key value of the IGrouping.
Console.WriteLine(packageGroup.Key);
// Iterate through each value in the
// IGrouping and print its value.
foreach (string str in packageGroup)
Console.WriteLine(" {0}", str);
}
}
/*
This code produces the following output:
C
Coho Vineyard 89453312
Contoso Pharmaceuticals 670053128
L
Lucerne Publishing 89112755
W
Wingtip Toys 299456122
Wide World Importers 4665518773
*/
///Dictionary例子
Dictionary<int, int?> ints2 = new Dictionary<int, int?> {{1, 5}, {2, 3}, {3, 9}, {4, 3}};
var isequal = ints2.ToLookup(p=>p.Value,
p=>p.Key+" "+p.Value);
foreach (var valuePair in isequal)
{
Console.WriteLine("{0} ",valuePair.Key);
foreach (var val in valuePair)
{
Console.WriteLine(" {0}",val);
}
}
Output:
5
1 5
3
2 3
4 3
9
3 9
```
ToLookup<TSource,TKey,TElement>(IEnumerable, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer)方法返回一个 Lookup<TKey,TElement> ,它是一个将键映射到值集合的一对多字典。 与 Lookup<TKey,TElement> 不同 Dictionary<TKey,TValue> ,后者执行从键到单个值的一对一映射。
执行方式
即时与推迟
即时执行是在代码中声明查询的位置读取数据来执行运算。
推迟执行是不在代码中声明查询的位置,在foreach中对查询的变量枚举的时候才执行运算。
流式与非流式
推迟执行的查询可分为流式处理和非流式处理
流式处理一边读取源元素一边执行运算,不需要读取全部的数据。
非流式处理是先读取所有的源数据再运算。
tips:如果某个运算符被标为流式处理与非流式处理,则表示在运算中涉及两个输入序列,每个序列的计算方式不同。 在此类情况下,参数列表中的第一个序列始终以延迟流式处理方式来执行计算。