Ritch Melton
Ritch Melton

Reputation: 11598

Selecting from one sequence based on a filter on a second sequence

There's nothing wrong with this code, but as a mental exercise I modified this:

public static IEnumerable<T> FiltersInnerWhere<T>(this IEnumerable<T> outer, IEnumerable<T> inner, Predicate<T> outerFilter)
{
    IEnumerator<T> outerEnumerator = outer.GetEnumerator();
    IEnumerator<T> innerEnumerator = inner.GetEnumerator();
    while (outerEnumerator.MoveNext() && innerEnumerator.MoveNext())
    {
        if (outerFilter(outerEnumerator.Current))
            yield return innerEnumerator.Current;
    }
}

To end up with this:

public static IEnumerable<T> FilteredMerge<T>(this IEnumerable<T> outer, IEnumerable<T> inner, Func<T, bool> outerFilter)
{
    var outerEnumerator = outer.GetEnumerator();
    var filtered = inner.Where(_ => outerEnumerator.MoveNext() && outerFilter(outerEnumerator.Current));
    return filtered;
}

Can it be done without grabbing the enumerator of the first directly in my code?

F# answers would be good also.

Upvotes: 1

Views: 110

Answers (1)

Reed Copsey
Reed Copsey

Reputation: 564413

You could do this via Enumerable.Zip and making a temporary:

var filtered = outer
       .Zip(inner, (o, i) => new {Outer = o, Inner = i})
       .Where(pair => outerFilter(pair.Outer))
       .Select(pair => pair.Inner);

It's definitely doing a bit of extra work (since there's the creation of the extra type in the middle), but it should provide the same results.

Upvotes: 2

Related Questions