【问题标题】:Does Linq/.NET3.5 support a 'zip' method?Linq/.NET3.5 是否支持“zip”方法?
【发布时间】:2011-02-18 04:51:40
【问题描述】:

在其他语言(ruby、python、...)中,我可以使用zip(list1, list2),其工作方式如下:

如果list1 is {1,2,3,4}list2 is {a,b,c}

然后zip(list1, list2) 将返回:{(1,a), (2,b), (3,c), (d,null)}

.NET 的 Linq 扩展中是否提供这种方法?

【问题讨论】:

    标签: .net linq list-manipulation


    【解决方案1】:

    .NET 4 为我们提供了一个 Zip 方法,但它在 .NET 3.5 中不可用。如果你好奇,Eric Lippert provides an implementation of Zip你可能会觉得有用。

    【讨论】:

    【解决方案2】:

    这两种实现都不会按照问题填写缺失值(或检查长度是否相同)。

    这是一个可以:

        public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first,  IEnumerable<TSecond> second,  Func<TFirst, TSecond, TResult> selector, bool checkLengths = true, bool fillMissing = false) {
            if (first == null)    { throw new ArgumentNullException("first");}
            if (second == null)   { throw new ArgumentNullException("second");}
            if (selector == null) { throw new ArgumentNullException("selector");}
    
            using (IEnumerator<TFirst> e1 = first.GetEnumerator()) {
                using (IEnumerator<TSecond> e2 = second.GetEnumerator()) {
                    while (true) {
                        bool more1 = e1.MoveNext();
                        bool more2 = e2.MoveNext();
    
                        if( ! more1 || ! more2) { //one finished
                            if(checkLengths && ! fillMissing && (more1 || more2)) { //checking length && not filling in missing values && ones not finished
                                throw new Exception("Enumerables have different lengths (" + (more1 ? "first" : "second") +" is longer)");
                            }
    
                            //fill in missing values with default(Tx) if asked too
                            if (fillMissing) {
                                if ( more1 ) {
                                    while ( e1.MoveNext() ) {
                                        yield return selector(e1.Current, default(TSecond));        
                                    }
                                } else {
                                    while ( e2.MoveNext() ) {
                                        yield return selector(default(TFirst), e2.Current);        
                                    }
                                }
                            }
    
                            yield break;
                        }
    
                        yield return selector(e1.Current, e2.Current);
                    }
                }
            }
        }
    

    【讨论】:

    • +1 用于注意“缺失值”行为。但是,这对我来说是一个错误 - 看起来 Python's zip function also 在到达其 shortest 参数的末尾时停止,就像 Linq 版本一样。 (我的假设 - 显示在问题中 - 是错误的)
    • 对于 zip 函数来说很奇怪,因此它默认为没有。但我遇到过一些情况是可取的。
    猜你喜欢
    • 2011-01-13
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2013-04-12
    相关资源
    最近更新 更多