2

我有 2 个列表:

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

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

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

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

4

6 回答 6

3

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

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

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

于 2011-07-07T19:46:49.557 回答
2

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

var myList = ListA.Except(ListB).ToList();
于 2011-07-07T19:47:24.037 回答
2

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

ListA = ListA.Except(ListB).ToList();
于 2011-07-07T19:48:44.933 回答
0

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

ListA.Join(ListB, ...);
于 2011-07-07T19:50:40.753 回答
0

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

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

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

于 2011-07-08T12:53:59.133 回答
0

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

于 2011-07-08T14:49:33.667 回答