Does Linq/.NET3.5 support a 'zip' method?

前端 未结 2 770
难免孤独
难免孤独 2021-01-12 21:17

In other languages (ruby, python, ...) I can use zip(list1, list2) which works like this:

If list1 is {1,2,3,4} and list2 is {a,b,c}<

2条回答
  •  广开言路
    2021-01-12 21:39

    neither implementation will fill in the missing values (or check that the lengths are the same) as the question asked.

    here is an implementation that can:

        public static IEnumerable Zip (this IEnumerable first,  IEnumerable second,  Func 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 e1 = first.GetEnumerator()) {
                using (IEnumerator 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);
                    }
                }
            }
        }
    

提交回复
热议问题