C#4.0新特性之(四)新的LINQ扩展方法-Zip()

C#4.0新特性之(四)新的LINQ扩展方法-Zip()

1.简介

  所谓zip(中文有拉链的意思),就是像拉链一样,把两个list缝合在一起。Python中有个zip函数可以用来方便的合并两个或者多个集合,例如:

>>>  firstName = [ ' Freesc ' , ' Joshua ' , ' Ken ' ]
>>>  lastName = [ ' Huang ' , ' Guan ' , ' Wang ' ]
>>>   for  f,l  in  zip(firstName,lastName):
    
print ( ' {0} {1} ' .format(f,l))

 以上代码会打印出

Freesc Huang
Joshua Guan
Ken Wang

在C#4.0中,我们可以看到一个类似的扩展函数[1]

ExpandedBlockStart.gif 代码2
         //
        
//  Summary:
        
//      Merges two sequences by using the specified predicate function.
        
//
        
//  Parameters:
        
//    first:
        
//      The first sequence to merge.
        
//
        
//    second:
        
//      The second sequence to merge.
        
//
        
//    resultSelector:
        
//      A function that specifies how to merge the elements from the two sequences.
        
//
        
//  Type parameters:
        
//    TFirst:
        
//      The type of the elements of the first input sequence.
        
//
        
//    TSecond:
        
//      The type of the elements of the second input sequence.
        
//
        
//    TResult:
        
//      The type of the elements of the result sequence.
        
//
        
//  Returns:
        
//      An System.Collections.Generic.IEnumerable<T> that contains merged elements
        
//      of two input sequences.
         public   static  IEnumerable < TResult >  Zip < TFirst, TSecond, TResult > ( this  IEnumerable < TFirst >  first, 
                                           IEnumerable
< TSecond >  second, 
                                           Func
< TFirst, TSecond, TResult >  resultSelector);

它可以用来合并列表,并且提供了自定义的组合规则:Func<TFirst, TSecond, TResult> resultSelector

2.示例

  下面是一段和代码1功能一样的C#4.0程序: 

ExpandedBlockStart.gif 代码3
            List < String >  firstName  =   new  List <S tring >  {  " Freesc " " Joshua " " Ken "  };
            List
< String >  lastName  =   new  List <S tring >  {  " Huang " " Guan " " Wang "  };
            
foreach  (var name  in  firstName.Zip(lastName, (fname, lname)  =>  fname  +   "   "   +  lname))
            {
                Console.WriteLine(name);
            }
 

3.Zip()的实现

  在python中要实现一个zip,很简单(这里省去了异常处理),只需要用到三个内建函数,iter,map和next:

def  zip( * iterables):
    
#  zip('ABCD', 'xy') --> Ax By
    iterables  =  map(iter, iterables)
    
while  iterables:
        
yield  tuple(map(next, iterables))
 

类似的,如果不考虑异常处理,C#的Zip扩展方法可以是如下实现[2]

ExpandedBlockStart.gif 代码5
     static   class  Enumerable
    {
        
public   static  IEnumerable < TResult >  Zip < TFirst, TSecond, TResult > ( this  IEnumerable < TFirst >  first,
            IEnumerable
< TSecond >  second,
            Func
< TFirst, TSecond, TResult >  func)
        {
            var ie1 
=  first.GetEnumerator();
            var ie2 
=  second.GetEnumerator();

            
while  (ie1.MoveNext()  &&  ie2.MoveNext())
                
yield   return  func(ie1.Current, ie2.Current);
        }
    }

4.总结

  Zip作为LINQ系统的新成员,提供了一种自由组合两个集合的方式,要注意的是,这个Zip使用时要求两个序列的长度一致,如果不一致,它会yield较短的长度。这一点和python中的zip是一样的。另外,您不妨可以试着写一个组合多个集合的MultiZip方法,也许它对您更加有用;-)

5.引用

[1] http://msdn.microsoft.com/en-us/library/dd267698(VS.100).aspx

[2] http://community.bartdesmet.net/blogs/bart/archive/2008/11/03/c-4-0-feature-focus-part-3-intermezzo-linq-s-new-zip-operator.aspx

 

AUTHOR: Freesc Huang @ CNBlogs

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值