Exemplo n.º 1
0
        private static IEnumerable <TResult> GroupJoin <TOuter, TInner, TKey, TResult>(
            IEnumerable <TOuter> outer,
            IEnumerable <TInner> inner,
            Func <TOuter, TKey> outerKeySelector,
            Func <TInner, TKey> innerKeySelector,
            Func <TOuter, IEnumerable <TInner>, TResult> resultSelector,
            IComparer <TKey> keyComparer)
        {
            using (var leftEnumerator = outer.GetEnumerator())
                using (var rightEnumerator = inner.GetEnumerator())
                {
                    EnumeratorState <TOuter> leftState  = leftEnumerator.Next();
                    EnumeratorState <TInner> rightState = rightEnumerator.Next();

                    while (leftState.HasCurrent && rightState.HasCurrent)
                    {
                        switch (keyComparer.Compare(outerKeySelector(leftState.Current), innerKeySelector(rightState.Current)))
                        {
                        case -1:
                            yield return(resultSelector(leftState.Current, new TInner[] { }));

                            leftState = leftEnumerator.Next();
                            break;

                        case 0:
                            TKey currentRightKey            = innerKeySelector(rightState.Current);
                            IReadOnlyList <TInner> elements = new[] { rightState.Current }
                            .Concat(rightEnumerator
                                    .TakeWhile(current => keyComparer.Compare(currentRightKey, innerKeySelector(current)) == 0, last => rightState = last))
                            .ToArray();

                            yield return(resultSelector(leftState.Current, elements));

                            TKey currentLeftKey = outerKeySelector(leftState.Current);
                            foreach (var leftItem in leftEnumerator.TakeWhile(current => keyComparer.Compare(currentLeftKey, outerKeySelector(current)) == 0, last => leftState = last))
                            {
                                yield return(resultSelector(leftItem, elements));
                            }
                            break;

                        case 1:
                            rightState = rightEnumerator.Next();
                            break;
                        }
                    }

                    while (leftState.HasCurrent)
                    {
                        yield return(resultSelector(leftState.Current, new TInner[] { }));

                        leftState = leftEnumerator.Next();
                    }
                }
        }
Exemplo n.º 2
0
        private static IEnumerable <TResult> Join <TOuter, TInner, TKey, TResult>(
            IEnumerable <TOuter> outer,
            IEnumerable <TInner> inner,
            Func <TOuter, TKey> outerKeySelector,
            Func <TInner, TKey> innerKeySelector,
            Func <TOuter, TInner, TResult> resultSelector,
            IComparer <TKey> keyComparer)
        {
            using (var leftEnumerator = outer.GetEnumerator())
                using (var rightEnumerator = inner.GetEnumerator())
                {
                    EnumeratorState <TOuter> leftState  = leftEnumerator.Next();
                    EnumeratorState <TInner> rightState = rightEnumerator.Next();

                    while (leftState.HasCurrent && rightState.HasCurrent)
                    {
                        switch (keyComparer.Compare(outerKeySelector(leftState.Current), innerKeySelector(rightState.Current)))
                        {
                        case -1:
                            leftState = leftEnumerator.Next();
                            break;

                        case 0:
                            yield return(resultSelector(leftState.Current, rightState.Current));

                            TKey          currentRightKey = innerKeySelector(rightState.Current);
                            List <TInner> elements        = new List <TInner> {
                                rightState.Current
                            };
                            foreach (TInner rightItem in rightEnumerator.TakeWhile(current => keyComparer.Compare(currentRightKey, innerKeySelector(current)) == 0, last => rightState = last))
                            {
                                elements.Add(rightItem);
                                yield return(resultSelector(leftState.Current, rightItem));
                            }

                            TKey currentLeftKey = outerKeySelector(leftState.Current);
                            foreach (var leftItem in leftEnumerator.TakeWhile(current => keyComparer.Compare(currentLeftKey, outerKeySelector(current)) == 0, last => leftState = last))
                            {
                                foreach (TInner rightItem in elements)
                                {
                                    yield return(resultSelector(leftItem, rightItem));
                                }
                            }
                            break;

                        case 1:
                            rightState = rightEnumerator.Next();
                            break;
                        }
                    }
                }
        }
Exemplo n.º 3
0
        private static IEnumerable <T> Distinct <T>(
            IEnumerable <T> source,
            IComparer <T> comparer)
        {
            using (var enumerator = source.GetEnumerator())
            {
                EnumeratorState <T> state = enumerator.Next();

                while (state.HasCurrent)
                {
                    yield return(state.Current);

                    state = enumerator.SkipWhile(current => comparer.Compare(state.Current, current) == 0);
                }
            }
        }
Exemplo n.º 4
0
        private static IEnumerable <T> Intersect <T>(
            IEnumerable <T> left,
            IEnumerable <T> right,
            IComparer <T> comparer)
        {
            using (var leftEnumerator = left.GetEnumerator())
                using (var rightEnumerator = right.GetEnumerator())
                {
                    EnumeratorState <T> leftState  = leftEnumerator.Next();
                    EnumeratorState <T> rightState = rightEnumerator.Next();

                    while (leftState.HasCurrent && rightState.HasCurrent)
                    {
                        switch (comparer.Compare(leftState.Current, rightState.Current))
                        {
                        case -1:
                            leftState = leftEnumerator.Next();
                            break;

                        case 0:
                            yield return(leftState.Current);

                            foreach (T item in leftEnumerator.TakeWhile(
                                         current => comparer.Compare(current, rightState.Current) == 0,
                                         last => leftState = last))
                            {
                                yield return(item);
                            }

                            yield return(rightEnumerator.Current);

                            foreach (T item in rightEnumerator.TakeWhile(
                                         current => comparer.Compare(current, rightState.Current) == 0,
                                         last => rightState = last))
                            {
                                yield return(item);
                            }
                            break;

                        case 1:
                            rightState = rightEnumerator.Next();
                            break;
                        }
                    }
                }
        }
Exemplo n.º 5
0
        private static IEnumerable <T> Except <T>(
            IEnumerable <T> left,
            IEnumerable <T> right,
            IComparer <T> comparer)
        {
            using (var leftEnumerator = left.GetEnumerator())
                using (var rightEnumerator = right.GetEnumerator())
                {
                    EnumeratorState <T> leftState  = leftEnumerator.Next();
                    EnumeratorState <T> rightState = rightEnumerator.Next();

                    while (leftState.HasCurrent && rightState.HasCurrent)
                    {
                        switch (comparer.Compare(leftState.Current, rightState.Current))
                        {
                        case -1:
                            yield return(leftState.Current);

                            leftState = leftEnumerator.Next();
                            break;

                        case 0:
                            leftState  = leftEnumerator.SkipWhile(current => comparer.Compare(leftState.Current, current) == 0);
                            rightState = rightEnumerator.SkipWhile(current => comparer.Compare(rightState.Current, current) == 0);
                            break;

                        case 1:
                            rightState = rightEnumerator.Next();
                            break;
                        }
                        ;
                    }

                    while (leftState.HasCurrent)
                    {
                        yield return(leftState.Current);

                        leftState = leftEnumerator.Next();
                    }
                }
        }
Exemplo n.º 6
0
        private static IEnumerable <IGrouping <TKey, T> > GroupBy <T, TKey>(
            IEnumerable <T> source,
            Func <T, TKey> keySelector,
            IComparer <TKey> keyComparer)
        {
            using (var enumerator = source.GetEnumerator())
            {
                EnumeratorState <T> state = enumerator.Next();

                while (state.HasCurrent)
                {
                    TKey groupKey = keySelector(state.Current);
                    IReadOnlyList <T> elements = new[] { state.Current }
                    .Concat(enumerator
                            .TakeWhile(current => keyComparer.Compare(groupKey, keySelector(current)) == 0, last => state = last))
                    .ToArray();

                    yield return(new Grouping <TKey, T>(groupKey, elements));
                }
            }
        }