public static void LinqDemo01() { string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var shortDigits = digits.Where((dd, aa) => dd.Length < aa); Console.WriteLine("Short digits:"); foreach (var d in shortDigits) Console.WriteLine("The Word {0} is shorter than its value.", d); }
輸出結(jié)果:
Short digits: The word five is shorter than its value. The word six is shorter than its value. The word seven is shorter than its value. The word eight is shorter than its value. The word nine is shorter than its value.
下面我們就來(lái)分析上述代碼中最核心的代碼:
digits.Where((dd, aa) => dd.Length < aa);
這行代碼都趕了些什么?
1、Where子句其實(shí)是用擴(kuò)展方法來(lái)實(shí)現(xiàn)的
如果你對(duì)擴(kuò)展方法不熟悉,請(qǐng)先看我之前的幾篇博客:
C#3.0 中的擴(kuò)展方法 (Extension Methods)
C#3.0 中使用擴(kuò)展方法來(lái)擴(kuò)展接口
Orcas Beta1 對(duì)多個(gè)同名擴(kuò)展方法的處理邏輯
微軟替我們實(shí)現(xiàn)的 Where 子句對(duì)應(yīng)的擴(kuò)展函數(shù)實(shí)際是如下的定義:
namespace System.Linq { public delegate TResult Func(TArg0 arg0, TArg1 arg1); public static class Enumerable { public static IEnumerable Where(this IEnumerable source, Func predicate); public static IEnumerable Where(this IEnumerable source, Func predicate); } }
public static void Demo01() { string[] text = { "Albert was here", "Burke slept late", "Connor is happy" }; var tt = text.SelectMany((s, index) => from ss in s.Split(' ') select new { Word = ss, Index = index }); foreach (var n in tt) Console.WriteLine("{0}:{1}", n.Word,n.Index); }
public static void Linq27() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var laterNumbers = numbers.SkipWhile((n, index) => n >= index); Console.WriteLine("All elements starting from first element less than its position:"); foreach (var n in laterNumbers) Console.WriteLine(n); }
輸出結(jié)果:
All elements starting from first element less than its position: 1 3 9 8 6 7 2 0
First 、FirstOrDefault、Any、All、Count 子句
注意:
101 LINQ Samples 中 First - Indexed、FirstOrDefault - Indexed、 Any - Indexed、All - Indexed、Count - Indexed 這五個(gè)例子在 Orcas Beta1中已經(jīng)不在可用,即下面代碼是錯(cuò)誤的。
public void Linq60() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int evenNum = numbers.First((num, index) => (num % 2 == 0) && (index % 2 == 0)); Console.WriteLine("{0} is an even number at an even position within the list.", evenNum); }
public void Linq63() { double?[] doubles = { 1.7, 2.3, 4.1, 1.9, 2.9 }; double? num = doubles.FirstOrDefault((n, index) => (n >= index - 0.5 && n <= index + 0.5)); if (num != null) Console.WriteLine("The value {1} is within 0.5 of its index position.", num); else Console.WriteLine("There is no number within 0.5 of its index position.", num); }
public void Linq68() { int[] numbers = { -9, -4, -8, -3, -5, -2, -1, -6, -7 }; bool negativeMatch = numbers.Any((n, index) => n == -index); Console.WriteLine("There is a number that is the negative of its index: {0}", negativeMatch); }
public void Linq71() { int[] lowNumbers = { 1, 11, 3, 19, 41, 65, 19 }; int[] highNumbers = { 7, 19, 42, 22, 45, 79, 24 }; bool allLower = lowNumbers.All((num, index) => num < highNumbers[index]); Console.WriteLine("Each number in the first list is lower than its counterpart in the second list: {0}", allLower); }
public void Linq75() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddEvenMatches = numbers.Count((n, index) => n % 2 == index % 2); Console.WriteLine("There are {0} numbers in the list whose odd/even status " + "matches that of their position.", oddEvenMatches); }
要實(shí)現(xiàn)這個(gè)功能,可以用Where 子句,如下:
public static void Linq60() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int evenNum = numbers.Where((num,index) =>( num % 2 == 0 && index %2 == 0) ).First(); Console.WriteLine("{0} is an even number at an even position within the list.", evenNum); }
public static void Linq63() { double?[] doubles = { 1.7, 2.3, 4.1, 1.9, 2.9 }; double? num = doubles.Where((n, index) => (n >= index - 0.5 && n <= index + 0.5)).FirstOrDefault(); if (num != null) Console.WriteLine("The value {1} is within 0.5 of its index position.", num); else Console.WriteLine("There is no number within 0.5 of its index position.", num); }
public static void Linq68() { int[] numbers = { -9, -4, -8, -3, -5, -2, -1, -6, -7 }; bool negativeMatch = numbers.Where((n, index) => n == -index).Any(); Console.WriteLine("There is a number that is the negative of its index: {0}", negativeMatch); }
public static void Linq71() { int[] lowNumbers = { 1, 11, 3, 19, 41, 65, 19 }; int[] highNumbers = { 7, 19, 42, 22, 45, 79, 24 }; bool allLower = lowNumbers.Where((num, index) => num < highNumbers[index]).All(n => true); Console.WriteLine("Each number in the first list is lower than its counterpart in the second list: {0}", allLower); }
public static void Linq75() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddEvenMatches = numbers.Where((n, index) => n % 2 == index % 2).Count(); Console.WriteLine("There are {0} numbers in the list whose odd/even status " + "matches that of their position.", oddEvenMatches); }