Linq 扩展函数的应用

xxx.Where((aa, bb) => aa.Length < bb);
明白以上代码是什么意思?(大家都是谈初学,高手浏览即可

1、Where子句其实是用扩展方法来实现的

MS实现的 Where 子句对应的扩展函数是如下的定义:

 

namespace System.Linq
{
    public delegate TResult Func<TArg0, TArg1, TResult>(TArg0 arg0, TArg1 arg1);
    public static class Enumerable
    {
        public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
        public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);
    }
}

其中红色字体的那个扩展函数,就是我们上面代码实际使用的扩展函数。

我们这个扩展函数参数:Func<TSource, int, bool> predicate 的定义看上面代码的绿色delegate 代码。

2、Where 子句参数书写的是Lambda 表达式

( (aa, bb) => aa.Length < bb); 就相当于 C# 2.0 的匿名函数。

 

LINQ中所有关键字比如 Select,SelectMany, Count, All 等等其实都是用扩展方法来实现的。上面的用法同样也适用于这些关键字子句。

3、这个Where子句中Lambda 表达式第二个参数是数组索引,我们可以在Lambda 表达式内部使用数组索引。来做一些复杂的判断。

具有数组索引的LINQ关键字除了Where还以下几个Select,SelectMany, Count, All

我们下面就来依次举例

Select 子句使用数组索引的例子

下面代码有一个整数数组,我们找出这个数字是否跟他在这个数组的位置一样

None.gif public   static   void  LinqDemo01()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif5413986720 };
ExpandedSubBlockStart.gifContractedSubBlock.gif    var numsInPlace 
= numbers.Select((num, index) => new dot.gif{ Num = num, InPlace = (num == index) });
InBlock.gif    Console.WriteLine(
"Number: In-place?");
InBlock.gif    
foreach (var n in numsInPlace)
InBlock.gif        Console.WriteLine(
"{0}: {1}", n.Num, n.InPlace);
ExpandedBlockEnd.gif}
 
None.gif
None.gif输出结果: 
None.gif
None.gifNumber: In
- place ?
None.gif
5 : False
None.gif
4 : False
None.gif
1 : False
None.gif
3 : True
None.gif
9 : False
None.gif
8 : False
None.gif
6 : True
None.gif
7 : True
None.gif
2 : False
None.gif
0 : False 
None.gif

其中我们用到的这个Select子句对应的扩展函数定义,以及其中Func<TSource, int, TResult>委托定义如下:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector);

public delegate TResult Func<TArg0, TArg1, TResult>(TArg0 arg0, TArg1 arg1);

SelectMany 子句使用数组索引的例子

几个句子组成的数组,我们希望把这几个句子拆分成单词,并显示每个单词在那个句子中。查询语句如下:

None.gif public   static   void  Demo01()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
string[] text = dot.gif"Albert was here"
InBlock.gif          
"Burke slept late"
ExpandedSubBlockEnd.gif          
"Connor is happy" }
;
ExpandedSubBlockStart.gifContractedSubBlock.gif    var tt 
= text.SelectMany((s, index) => from ss in s.Split(' ') select new dot.gif{ Word = ss, Index = index });
InBlock.gif    
foreach (var n in tt)
InBlock.gif        Console.WriteLine(
"{0}:{1}", n.Word,n.Index);
ExpandedBlockEnd.gif}
 
None.gif
None.gif结果:
None.gif
None.gifAlbert:
0
None.gifwas:
0
None.gifhere:
0
None.gifBurke:
1
None.gifslept:
1
None.giflate:
1
None.gifConnor:
2
None.gif
is : 2
None.gifhappy:
2  
None.gif
None.gif 
None.gif

SkipWhile 子句使用数组索引的例子

SkipWhile 意思是一直跳过数据,一直到满足表达式的项时,才开始返回数据,而不管之后的项是否仍然满足表达式,需要注意他跟Where是不一样的,Where是满足条件的记录才返回,SkipWhile 是找到一个满足条件的,然后后面的数据全部返回。

下面例子返回一个整数数组中,这个整数比他自身在这个数组的位置大于等于的第一个位置以及之后的数据。

None.gif public   static   void  Linq27()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif5413986720 };
InBlock.gif    var laterNumbers 
= numbers.SkipWhile((n, index) => n >= index);
InBlock.gif    Console.WriteLine(
"All elements starting from first element less than its position:");
InBlock.gif    
foreach (var n in laterNumbers)
InBlock.gif        Console.WriteLine(n);
ExpandedBlockEnd.gif}
 
None.gif
None.gif输出结果:
None.gif
None.gifAll elements starting from first element less than its position:
None.gif
1
None.gif
3
None.gif
9
None.gif
8
None.gif
6
None.gif
7
None.gif
2
None.gif
0  
None.gif
None.gif 
None.gif

First 、FirstOrDefault、Any、All、Count 子句

注意:

101 LINQ Samples 中 First - Indexed、FirstOrDefault - Indexed、 Any - Indexed、All - Indexed、Count - Indexed 这五个例子在 Orcas Beta1中已经不在可用,即下面代码是错误的。

ExpandedBlockStart.gif ContractedBlock.gif public   void  Linq60()  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif5413986720 };
InBlock.gif    
int evenNum = numbers.First((num, index) => (num % 2 == 0&& (index % 2 == 0));
InBlock.gif    Console.WriteLine(
"{0} is an even number at an even position within the list.", evenNum);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   void  Linq63()  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
double?[] doubles = dot.gif1.72.34.11.92.9 };
InBlock.gif    
double? num = doubles.FirstOrDefault((n, index) => (n >= index - 0.5 && n <= index + 0.5));
InBlock.gif    
if (num != null)
InBlock.gif        Console.WriteLine(
"The value {1} is within 0.5 of its index position.", num);
InBlock.gif    
else
InBlock.gif        Console.WriteLine(
"There is no number within 0.5 of its index position.", num);
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   void  Linq68()  dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif   
int[] numbers = dot.gif-9-4-8-3-5-2-1-6-7 }
InBlock.gif   
bool negativeMatch = numbers.Any((n, index) => n == -index); 
InBlock.gif   Console.WriteLine(
"There is a number that is the negative of its index: {0}", negativeMatch); 
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   void  Linq71()  dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif   
int[] lowNumbers = dot.gif111319416519 }
ExpandedSubBlockStart.gifContractedSubBlock.gif   
int[] highNumbers = dot.gif7194222457924 }
InBlock.gif   
bool allLower = lowNumbers.All((num, index) => num < highNumbers[index]); 
InBlock.gif   Console.WriteLine(
"Each number in the first list is lower than its counterpart in the second list: {0}", allLower); 
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   void  Linq75()  dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif   
int[] numbers = dot.gif5413986720 };
InBlock.gif   
int oddEvenMatches = numbers.Count((n, index) => n % 2 == index % 2);
InBlock.gif   Console.WriteLine(
"There are {0} numbers in the list whose odd/even status " + 
InBlock.gif        
"matches that of their position.", oddEvenMatches); 
ExpandedBlockEnd.gif}
 
None.gif
None.gif要实现这个功能,可以用Where 子句,如下:
None.gif
None.gif
public   static   void  Linq60()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif5413986720 };
InBlock.gif    
int evenNum = numbers.Where((num,index) =>( num % 2 == 0 && index %2 == 0) ).First();
InBlock.gif    Console.WriteLine(
"{0} is an even number at an even position within the list.", evenNum);
ExpandedBlockEnd.gif}
 
None.gif
None.gif
public   static   void  Linq63()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
double?[] doubles = dot.gif1.72.34.11.92.9 };
InBlock.gif    
double? num = doubles.Where((n, index) => (n >= index - 0.5 && n <= index + 0.5)).FirstOrDefault();
InBlock.gif    
if (num != null)
InBlock.gif        Console.WriteLine(
"The value {1} is within 0.5 of its index position.", num);
InBlock.gif    
else
InBlock.gif        Console.WriteLine(
"There is no number within 0.5 of its index position.", num);
ExpandedBlockEnd.gif}
 
None.gif
None.gif
public   static   void  Linq68()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif-9-4-8-3-5-2-1-6-7 };
InBlock.gif    
bool negativeMatch = numbers.Where((n, index) => n == -index).Any();
InBlock.gif    Console.WriteLine(
"There is a number that is the negative of its index: {0}", negativeMatch);
ExpandedBlockEnd.gif}
 
None.gif
None.gif
public   static   void  Linq71()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] lowNumbers = dot.gif111319416519 };
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] highNumbers = dot.gif7194222457924 };
InBlock.gif    
bool allLower = lowNumbers.Where((num, index) => num < highNumbers[index]).All(n => true);
InBlock.gif    Console.WriteLine(
"Each number in the first list is lower than its counterpart in the second list: {0}", allLower);
ExpandedBlockEnd.gif}
 
None.gif
None.gif
public   static   void  Linq75()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
int[] numbers = dot.gif5413986720 };
InBlock.gif    
int oddEvenMatches = numbers.Where((n, index) => n % 2 == index % 2).Count();
InBlock.gif    Console.WriteLine(
"There are {0} numbers in the list whose odd/even status " +
InBlock.gif         
"matches that of their position.", oddEvenMatches);
ExpandedBlockEnd.gif}
 
None.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值