gpt4 book ai didi

c# - 如何有效地从(最初)大量对象列表中过滤对象

转载 作者:行者123 更新时间:2023-11-30 20:40:24 28 4
gpt4 key购买 nike

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

目前我使用以下算法:

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

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

  1. 创建子列表的过滤发生在我的对象的最多 7 个属性上。有没有办法提高 Linq > Where 选择的性能?
  2. 有没有办法通过使用 Except 或 RemoveAll(可能的改进)来防止项目被选入多个子列表,而不减少工作集合?

提前致谢!

最佳答案

如果您无法利用您尝试分类的传入列表中的任何索引,那么您最好只遍历整个列表一次并在进行时对项目进行分类。这样您就可以避免不必要的 removeexcept 操作,这些操作会通过无意义的迭代和相等比较严重损害性能。

我一直在想一些事情:

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<???>使用您需要的任何签名。

编辑:编辑代码以处理“默认存储桶”,不符合任何指定谓词的项目将进入该存储桶。

关于c# - 如何有效地从(最初)大量对象列表中过滤对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33417464/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com