题记:最近的目标是熟悉常用类的一些比较高效的用法,为了方便自己整理,所以从MSDN记录了下来,比较凌乱,都是一些例子(NET4.0)。
通过使用指定的谓词函数合并两个序列
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,Func<TFirst, TSecond, TResult> resultSelector)
示例:
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);
foreach (var item in numbersAndWords)
Console.WriteLine(item);
// 1 one
// 2 two
// 3 three
基于谓词筛选值序列。 将在谓词函数的逻辑中使用每个元素的索引
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource, int, bool> predicate)
示例:
int[] numbers = { 0, 30, 20, 15, 90, 85, 40, 75 };
IEnumerable<int> query =
numbers.Where((number, index) => number <= index * 10);
foreach (int number in query)
{
Console.WriteLine(number);
}
/*
This code produces the following output:
0
20
15
40
*/
计算 Single 值序列的和,这些值是通过对输入序列中的每个元素调用转换函数得来的
public static float Sum<TSource>(this IEnumerable<TSource> source,Func<TSource, float> selector)
示例:
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
}
public static void Main()
{
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 } };
double totalWeight = packages.Sum(pkg => pkg.Weight);
Console.WriteLine("The total weight of the packages is: {0}", totalWeight);
}
/*
The total weight of the packages is: 83.7
*/
只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素
public static IEnumerable<TSource> SkipWhile<TSource>(
this IEnumerable<TSource> source,Func<TSource, bool> predicate)
示例:
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);
}
/*
All grades below 80:
70
59
56
*/
调用序列的每个元素上的转换函数并返回最小 Int32 值。
public static int Min<TSource>(this IEnumerable<TSource> source,Func<TSource, int> selector)
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void Main()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };
int min = pets.Min(pet => pet.Age);
Console.WriteLine("The youngest animal is age {0}.", min);
}
/*
The youngest animal is age 1.
*/
返回一个 Int64,表示序列中满足条件的元素的数量
public static long LongCount<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate)
示例:
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void Main()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };
const int Age = 3;
long count = pets.LongCount(pet => pet.Age > Age);
Console.WriteLine("There are {0} animals over age {1}.", count, Age);
}
/*
There are 2 animals over age 3.
*/
返回序列中满足指定条件的最后一个元素
public static TSource Last<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
示例:
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 67, 12, 19 };
int last = numbers.Last(num => num > 80);
Console.WriteLine(last);
/*
87
*/
根据指定的键选择器函数对序列中的元素进行分组,并且通过使用指定的函数对每个组中的元素进行投影
public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector
)
示例:
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void GroupByEx1()
{
// Create a list of pets.
List<Pet> pets =
new List<Pet>{ new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 },
new Pet { Name="Daisy", Age=4 } };
IEnumerable<IGrouping<int, string>> query =
pets.GroupBy(pet => pet.Age, pet => pet.Name);
foreach (IGrouping<int, string> petGroup in query)
{
Console.WriteLine(petGroup.Key);
foreach (string name in petGroup)
Console.WriteLine(" {0}", name);
}
}
/*
8
Barley
4
Boots
Daisy
1
Whiskers
*/
基于匹配键对两个序列的元素进行关联。 使用默认的相等比较器对键进行比较
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector
)
outer
类型:System.Collections.Generic.IEnumerable<TOuter>
要联接的第一个序列。
inner
类型:System.Collections.Generic.IEnumerable<TInner>
要与第一个序列联接的序列。
outerKeySelector
类型:System.Func<TOuter, TKey>
用于从第一个序列的每个元素提取联接键的函数。
innerKeySelector
类型:System.Func<TInner, TKey>
用于从第二个序列的每个元素提取联接键的函数。
resultSelector
类型:System.Func<TOuter, TInner, TResult>
用于从两个匹配元素创建结果元素的函数。
示例:
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<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };
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);
}
}
/*
Hedlund, Magnus - Daisy
Adams, Terry - Barley
Adams, Terry - Boots
Weiss, Charlotte - Whiskers
*/
返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值
public static TSource FirstOrDefault<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
示例:
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");
/*
The first long name is 'Andersen, Henriette Thaulow'.
There is not a name longer than 30 characters.
*/
通过使用默认的相等比较器对值进行比较生成两个序列的差集
public static IEnumerable<TSource> Except<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second
)
double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 };
IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);
foreach (double number in onlyInFirstSet)
Console.WriteLine(number);
/*
2
2.1
2.3
2.4
2.5
*/
通过使用默认的相等比较器对值进行比较返回序列中的非重复元素
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source)
示例:
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);
}
/*
Distinct ages:
21
46
55
17
*/
返回一个数字,表示在指定的序列中满足条件的元素数量
public static int Count<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
示例:
class Pet
{
public string Name { get; set; }
public bool Vaccinated { get; set; }
}
public static void CountEx2()
{
Pet[] pets = { new Pet { Name="Barley", Vaccinated=true },
new Pet { Name="Boots", Vaccinated=false },
new Pet { Name="Whiskers", Vaccinated=false } };
try
{
int numberUnvaccinated = pets.Count(p => p.Vaccinated == false);
Console.WriteLine("There are {0} unvaccinated animals.", numberUnvaccinated);
}
catch (OverflowException)
{
Console.WriteLine("The count is too large to store as an Int32.");
Console.WriteLine("Try using the LongCount() method instead.");
}
}
// There are 2 unvaccinated animals.
计算可以为 null 的 Int32 值序列的平均值,该值可通过调用输入序列的每个元素的转换函数获取
publicstatic Nullable<double> Average<TSource>(
this IEnumerable<TSource> source,
Func<TSource, Nullable<int>> selector
)
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };
double average = fruits.Average(s => s.Length);
Console.WriteLine("The average string length is {0}.", average);
//
// The average string length is 6.5.
确定序列中的任何元素是否都满足条件
public static bool Any<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
示例:
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
public bool Vaccinated { get; set; }
}
public static void AnyEx3()
{
// Create an array of Pets.
Pet[] pets =
{ new Pet { Name="Barley", Age=8, Vaccinated=true },
new Pet { Name="Boots", Age=4, Vaccinated=false },
new Pet { Name="Whiskers", Age=1, Vaccinated=false } };
// Determine whether any pets over age 1 are also unvaccinated.
bool unvaccinated =
pets.Any(p => p.Age > 1 && p.Vaccinated == false);
Console.WriteLine(
"There {0} unvaccinated animals over age one.",
unvaccinated ? "are" : "are not any");
}
// There are unvaccinated animals over age one.