如何有效地从(最初)大的对象列表中筛选对象
本文关键字:对象 列表 筛选 有效地 最初 | 更新日期: 2023-09-27 18:19:50
我需要将一个复杂(20多个属性)对象的大列表过滤成多个子列表。为了创建子列表,我有一个过滤器规范的列表。要求是:a)一个项目不允许成为两个子清单的一部分,b)必须能够在处理完成后获得所有未分割的项目。
目前我使用以下算法:
- 列出项目
- 将要筛选的对象放在泛型列表中
- 对于每个过滤器规格:
- 创建Where表达式(表达式>)
- 使用Linq>Where将表达式应用于对象列表
- 获取所选对象的结果IEnumerable,并将其与筛选器的描述一起存储在列表中
- 使用Linq>从源列表中删除找到的项目。除了创建一个新列表以继续使用并防止对象被放入多个子列表之外
- 检查工作列表中是否有静止的(未分割的)对象
我最初的对象列表可能超过400000个对象,我注意到过滤和减少工作列表都需要一些时间。所以我想知道:
- 筛选以创建子列表最多在我的对象的7个属性上进行。有没有办法提高Linq>Where选择的性能
- 是否有一种方法可以防止项目被选择到多个子列表中,而不使用Except或RemoveAll来减少工作集合(可能的改进)
提前感谢!
如果你不能利用你试图分类的传入列表中的任何索引,那么你最好只在整个列表中迭代一次,并在进行时对项目进行分类。通过这种方式,您可以避免不必要的删除和,除非操作会通过无意义的迭代和相等比较严重损害性能。
我在想一件很长的事情:
public static IDictionary<string, List<T>> Classify<T>(this IEnumerable<T> items, IDictionary<string, Predicate<T>> predicates, out List<T> defaultBucket)
{
var classifiedItems = new Dictionary<string, List<T>>(predicates.Count);
defaultBucket = new List<T>();
foreach (var predicate in predicates)
{
classifiedItems.Add(predicate.Key, new List<T>());
}
foreach (var item in items)
{
var matched = false;
foreach (var predicate in predicates)
{
if (predicate.Value(item))
{
matched = true;
classifiedItems[predicate.Key].Add(item);
break;
}
}
if (!matched)
{
defaultBucket.Add(item);
}
}
return classifiedItems;
}
任何给定的predicate
都可以根据您的需要进行复杂处理。唯一的条件是它接受T
并返回bool
。如果这还不够,那么没有什么可以阻止您使用所需的任何签名来实现自己的MyPredicate<???>
。
EDIT:编辑代码以处理不符合任何指定谓词的项所在的"默认bucket"。