Фильтрация подмножеств с использованием Linq - PullRequest
0 голосов
/ 12 мая 2010

Представьте, что у вас очень длинное перечисление, слишком большое, чтобы его можно было разумно преобразовать в список. Представьте также, что я хочу удалить дубликаты из списка. Наконец, представьте, что я знаю, что только небольшое подмножество начального перечисления может содержать дубликаты. Последний пункт делает проблему практической.

По сути, я хочу отфильтровать список на основе некоторого предиката и вызвать только Distinct () для этого подмножества, но также выполнить рекомбинацию с перечислением, в котором предикат вернул false.

Кто-нибудь может подумать о хорошем идиоматическом способе Linq сделать это? Я полагаю, что вопрос сводится к следующему:

Как в Linq можно выполнить выборочную обработку для предикатного перечисления и рекомбинировать поток результатов с отклоненными случаями из предиката?

Ответы [ 2 ]

0 голосов
/ 13 мая 2010

Не могли бы вы рассказать немного подробнее о том, как бы вы хотели рекомбинировать элементы.

Один из способов решения этой проблемы - использовать оператор Zip .Net 4.0 следующим образом.

var initialList  = new List<int>();

    var resjectedElemnts = initialList.Where( x=> !aPredicate(x) );
    var accepetedElements = initialList.Where( x=> aPredicate(x) );

    var result = accepetedElements.Zip(resjectedElemnts,(accepted,rejected) => T new {accepted,rejected});

Это создаст список пар отклоненных и принятых элементов. Но размер списка будет ограничен более коротким списком между двумя входами.

0 голосов
/ 12 мая 2010

Вы можете сделать это, пройдя по списку дважды, один раз, чтобы применить предикат и дедупликацию, и второй раз, чтобы применить отрицание предиката.Другое решение - написать собственный вариант метода расширения Where, который помещает несовпадающие записи в буфер на стороне:

IEnumerable<T> WhereTee(this IEnumerable<T> input, Predicate<T> pred, List<T> buffer)
{
    foreach (T t in input)
    {
        if (pred(t))
        {
            yield return t;
        }
        else
        {
            buffer.Add(t);
        }
    }
}
...