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

本文关键字:异常 修改 集合 方法 有效 遇到 列表 删除 | 更新日期: 2023-09-27 18:01:24

我有两个列表:

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循环。我只是想知道这个问题的最佳解决方案是什么,以及遵循什么标准准则。

如果我做错了,我很想知道。我的主要目标是使用键作为比较,从DictA中删除不在DictA中的所有内容。

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

如果您需要结果保持不变并且独立于以后的更改,只需在查询中调用ToList()ToArray()来获得一个具体的结果。

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

对任何一个源输入的更改都不会影响您现在完全计算的查询。

为什么不直接使用即时求值呢?

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

出于同样的原因,我使用next:

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

也许你是在反向操作。"从DictA中删除不在DictB中的所有内容"的另一种说法是"保留DictA中也在DictB中的所有内容"。而不是试图从ListA中删除东西,只是创建一个新的列表:

ListA.Join(ListB, ...);

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

如果你想要两个字典的交集,那么你应该这样做:

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

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