繁体   English   中英

从另一个列表中删除列表项

[英]Removing list item from another list

我有一个包含一些元素的列表,我想从另一个列表中删除元素。 如果某个项目的值Contain (而不是)另一个列表中的值,则应删除该项目。

一种方法是执行此操作:

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

有用...

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

创建循环很容易做到这一点,但是有没有办法对已排序的集合执行此操作?


更新:

在包含禁止列表的文本上进行20k次迭代后,我得到以下信息:

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

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

多次运行后保持一致,因此哈希集速度较慢

好吧,由于二进制搜索O(log n)复杂性,排序ToRemove可能是有益的(您将需要重写_ => ToRemove.Any(_.Contains) )。

但是,相反,对于ToRemove使用HashSet<string>而不是List<string>会更快,因为在哈希集中查找元素(使用Contains )是O(1)操作。

同样,对MyList使用LinkedList<string>可能会有好处,因为由于数组大小的调整,从链接列表中删除项目通常比从基于数组的列表中删除要快。

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

暂无
暂无

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

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