Выбор из одной последовательности на основе фильтра во второй последовательности

59
6

В этом коде нет ничего плохого, но в качестве умственного упражнения я изменил это:

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;
}
}

Чтобы это получилось:

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;
}

Можно ли это сделать, не перехватывая перечислитель первого непосредственно в моем коде?

Ответы F # также были бы хороши.

спросил(а) 2011-09-17T04:03:00+04:00 9 лет, 2 месяца назад
1
Решение
72

Вы можете сделать это через Enumerable.Zip и сделать временный:

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

Это определенно делает немного дополнительной работы (поскольку там создается дополнительный тип в середине), но он должен давать те же результаты.

ответил(а) 2011-09-17T04:07:00+04:00 9 лет, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема