【问题标题】:Removing list item from another list从另一个列表中删除列表项
【发布时间】:2018-10-24 23:55:38
【问题描述】:

我有一个包含一些元素的列表,我想从另一个列表中删除元素。 如果一个项目的值Contains(不等于)另一个列表中的值,则应该删除它。

其中一种方法是这样做:

var MyList = new List<string> { ... }
var ToRemove = new List<string> { ... }
MyList.RemoveAll(_ => ToRemove.Any(_.Contains));

它有效...

但是,我有 LOT 个列表(>100 万),并且由于 ToRemove 可以排序,因此使用它来加快处理速度是有意义的。

创建一个循环很容易,但是有没有办法通过排序的集合来做到这一点?


更新:

在包含我们禁止列表的文本上进行 20k 次迭代时,我得到了这个:

禁止列表作为列表 -> 00:00:07.1993364

禁止列表作为 HashSet -> 00:00:07.9749997

多次运行后是一致的,所以hashset比较慢

【问题讨论】:

  • 您有超过一百万个列表?还是列出项目?
  • @Rufus:我知道如何对列表进行排序,我想说的是,如果对包含要排除的单词的列表进行排序,该过程可能会快很多,但我正在尝试看看如何使用 c# 集合来做到这一点。
  • @Camilo:我有超过一百万个列表,每个列表大约有 7-10 个单词
  • OP,您当前的代码像 this 一样工作是否正确 - 您想从 MyList 中删除字符串项,其中该字符串部分包含来自 ToRemove 的值?
  • 我们可能会有一些误报,但没关系,由于数量庞大,丢失部分数据是个问题

标签: c# .net collections


【解决方案1】:

由于这是删除包含另一个列表中的字符串的字符串,因此 HashSet 不会有太大帮助。实际上,除非您正在寻找完全匹配或维护所有子字符串的索引(昂贵且仅 AFIK 的 SQL Server 在 BigData 领域之外半有效地执行此操作),否则实际上并没有多少。 如果您关心的只是它是否以“ToRemove”中的项目开头,那么排序可能会有所帮助。在 'ToRemove' 自定义二进制搜索中对 'MyList' 和 foreach 字符串进行排序,以查找以该字符串和 RemoveAt 索引开头的任何字符串,直到 not 开头,然后递减索引向后删除直到 not 开头。

【讨论】:

  • 您能否详细说明为什么HashSet 没有多大帮助?
  • @Alex 他是对的,事实上。 MyList 是 List&lt;string&gt; 类型,并且 OP 在 MyList 中为 ToRemove 的每个项目调用 .Contains()(即“MyList 字符串中的任何位置是否包含 ToRemove 中的单词?”) - Example
  • 我明白了,有道理。
  • 感谢您为我处理这些 cmets。我已经编码 30 年了,但不是社交媒体,所以我最近才开始发帖,昨天才获得评论的特权。
【解决方案2】:

好吧,排序ToRemove 可能是有益的,因为二进制搜索O(log n) 很复杂(您需要重写_ =&gt; ToRemove.Any(_.Contains))。

但是,相反,使用HashSet&lt;string&gt; 而不是List&lt;string&gt; 来代替ToRemove 会快得多,因为在哈希集中查找元素(使用Contains)是O(1) 操作。

此外,将LinkedList&lt;string&gt; 用于MyList 可能是有益的,因为由于数组大小调整,从链表中删除项目通常比从基于数组的列表中删除更快。

【讨论】:

  • 我想到了哈希集,但这带来了另一个问题:为了进行匹配,必须对 MyList 中的每个字符串进行哈希处理;而在纯字符串比较中,第一步是匹配长度,因此许多字符串会立即被拒绝而不会被扫描;我正在寻找最佳解决方案,因为我们一直在获取新数据。
  • @Thomas 每次您想根据 ToRemove 的内容从众多列表之一中删除项目时,散列 ToRemove 列表的成本肯定低于迭代它的成本?
  • 好吧,List&lt;string&gt; 可能比HashSet&lt;string&gt; 更快,只是对于非常小的尺寸。但是如果它很小,你真的不需要关心性能,因为它无论如何都会很快(同样的,如果列表很小,二进制搜索实际上可能更昂贵)
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 2013-09-20
  • 2016-11-06
  • 1970-01-01
相关资源
最近更新 更多