想象一个很长的枚举,太大而无法合理地转换为列表。还想象一下,我想从列表中删除重复项。最后想象一下,我知道只有一小部分初始枚举可能包含重复项。最后一点使问题变得实用。
基本上,我想根据一些谓词过滤掉列表,只在该子集上调用 Distinct(),但还要与谓词返回 false 的枚举重新组合。
谁能想到一个好的惯用的 Linq 方式来做到这一点?我想问题归结为以下几点:
使用 Linq,您如何对谓词枚举执行选择性处理并将结果流与谓词中的拒绝案例重新组合?
您可以通过遍历列表两次来做到这一点,一次应用谓词和去重,第二次应用谓词的否定。另一种解决方案是编写您自己的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);
}
}
}
你能提供更多关于你想如何重组元素的细节吗?
我能想到的解决这个问题的一种方法是像这样使用.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});
这将创建一对被拒绝和接受的元素列表。但是列表的大小将受到两个输入之间较短的列表的限制。