使用Linq过滤子集

时间:2010-05-12 08:31:16

标签: linq distinct predicate subset

想象一下,有一个很长的枚举,太大而无法合理地转换为列表。想象一下,我想从列表中删除重复项。最后想象一下,我知道只有初始枚举的一小部分可能包含重复项。最后一点使问题变得切实可行。

基本上我想基于某个谓词筛选出列表,只调用该子集上的Distinct(),但也重新组合谓词返回false的枚举。

任何人都可以想到一个好的惯用Linq这样做的方式吗?我想这个问题归结为以下几点:

使用Linq,如何对谓词枚举执行选择性处理,并将结果流与谓词中的被拒绝案例重新组合?

2 个答案:

答案 0 :(得分:0)

您可以通过遍历列表两次,一次应用谓词和重复数据删除,第二次遍历谓词的否定来实现。另一个解决方案是编写自己的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);
        }
    }
}

答案 1 :(得分:0)

您能否提供一些关于如何重新组合这些元素的详细信息。

我能想到解决这个问题的一种方法是使用.Net 4.0的Zip运算符。

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

这将创建一对被拒绝和已加入元素的列表。但是列表的大小将受到两个输入之间较短列表的限制。