繁体   English   中英

从列表中删除项目而不遇到集合修改异常的最有效方法?

[英]Most efficient way to remove items from a list without running into a collection modified exception?

我有 2 个列表:

ListA { 'A', 'B', 'C' } //ListA is DictA.Keys
ListB { 'B', 'X', 'Y' } //ListB is DictB.Keys

如果我执行ListA.Except(ListB) ,我会返回一个 exceptIterator,它可以让我在 ListA 上迭代任何不在 ListB 中的项目。 问题是它的实现也是简单地使用 ListA (出于某种原因,我认为它会创建一个新的项目集合,这些项目是不同的)。 好吧,我发现它仍然使用 ListA 作为源,但只是使用了一种特殊类型的迭代器。 因此,当然,当我从 ListA 中删除一个项目时,它会抱怨该集合已被修改。

我可以想出几种方法来做我想做的事,首先是复制 ListA 并在副本上执行 except。 第二个是只做一个while循环。 我只是想知道这个问题的最佳解决方案是什么,以及什么遵循标准指南。

如果我以错误的方式解决这个问题,我很想知道这一点。 我的主要目标是使用键作为比较从不在 DictB 中的 DictA 中删除所有内容。

如果您需要保留结果并独立于以后的更改,只需通过在查询中调用ToList()ToArray()来获得具体结果。

var query = list1.Except(list2).ToList(); 

对任一源输入的更改都不会影响您现在完全评估的查询。

为什么不直接使用热切评估?

var myList = ListA.Except(ListB).ToList();

出于同样的原因,我使用下一个:

ListA = ListA.Except(ListB).ToList();

也许你正在倒退。 另一种说法是“从 DictA 中删除不在 DictB 中的所有内容”是说“所有内容保留在 DictA 中但也在 DictB 中”。 与其尝试从 ListA 中删除东西,不如创建一个新列表:

ListA.Join(ListB, ...);

如果你想要两个字典的交集,那么这就是你要做的:

IEnumerable<KeyValuePair<Char, String>> result = DictB.Intersect<KeyValuePair<Char, String>>(DictA);

这将返回 DictA 中与 DictB 匹配的所有项目。 此外,对于示例,我假设键是 Char 类型,值是 String 类型。 如果您的不同,只需为您的解决方案设置正确的类型。 要查看实际结果,您必须发送 result.GetEnumerator() 或在 foreach 语句中使用它。

如果您可以控制相关数据结构,那么定义一个接受谓词(接受列表数据类型并返回布尔值的 function)并删除谓词返回 true 的所有项目的 Purge 方法可能很有用(我希望 Microsoft 已经定义了一个 IPurgeableCollection,因为对于许多正常的 Microsoft 集合来说,实现这样的例程并不存在固有的困难)。 请注意,在许多情况下,集合实现 Purge 方法比允许在枚举期间进行一般修改要容易得多,而且在许多情况下,这样的方法不仅可以避免创建数据的额外副本以被删除,但它也可以大大减少执行删除所需的工作量(例如,在清除字典时,不必查找要删除的每个键,因为在枚举期间已经找到它)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM