如何有效地从(最初)大的对象列表中筛选对象



我需要将一个复杂(20多个属性)对象的大列表过滤成多个子列表。为了创建子列表,我有一个过滤器规范的列表。要求是:a)一个项目不允许成为两个子清单的一部分,b)必须能够在处理完成后获得所有未分割的项目。

目前我使用以下算法:

  1. 列出项目
  2. 将要筛选的对象放在泛型列表中
  3. 对于每个过滤器规格:
    • 创建Where表达式(表达式>)
    • 使用Linq>Where将表达式应用于对象列表
    • 获取所选对象的结果IEnumerable,并将其与筛选器的描述一起存储在列表中
    • 使用Linq>从源列表中删除找到的项目。除了创建一个新列表以继续使用并防止对象被放入多个子列表之外
  4. 检查工作列表中是否有静止的(未分割的)对象

我最初的对象列表可能超过400000个对象,我注意到过滤和减少工作列表都需要一些时间。所以我想知道:

  1. 筛选以创建子列表最多在我的对象的7个属性上进行。有没有办法提高Linq>Where选择的性能
  2. 是否有一种方法可以防止项目被选择到多个子列表中,而不使用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"。

最新更新