C# - 将 2 个列表与自定义元素进行比较

标签 c# list for-loop iterator

我有 2 个列表。一个包含搜索元素,一个包含数据。 我需要循环 list2 中的每个元素,其中包含 list1 中的任何字符串(“cat”或“dog”)。例如:

List<string> list1 = new List<string>();
list1.Add("Cat");
list1.Add("Dog");
list1.Add... ~1000 items;

List<string> list2 = new List<string>();
list2.Add("Gray Cat");
list2.Add("Black Cat");
list2.Add("Green Duck");
list2.Add("White Horse");
list2.Add("Yellow Dog Tasmania");
list2.Add("White Horse");
list2.Add... ~million items;

我的期望是 listResult: {"Gray Cat", "Black Cat", "Yellow Dog Tasmania"}(因为它在 list1 中包含“cat”和“dog”)。除了嵌套循环,您有什么想法可以让序列运行得更快吗?

我目前的解决方案如下。但是...它似乎太慢了:

foreach (string str1 in list1)
{
   foreach (string str2 in list2)
   {
      if str2.Contains(str1)
      {
         listResult.Add(str2);
      }
   }
}

最佳答案

并行化的绝佳用例!

没有并行化的 Linq 方法(在内部等于你的方法,除了如果找到一个匹配项内部循环就会中断 - 你的方法也会搜索其他匹配项)

List<string> listResult = list2.Where(x => list1.Any(x.Contains)).ToList();

使用 AsParallel() 将循环并行化 - 如果您有一个多核系统,将会有巨大的性能提升。

List<string> listResult = list2.AsParallel().Where(x => list1.Any(x.Contains)).ToList();

运行时比较: (4个核心系统,list1 1000条,list2 1.000.000条)

Without AsParallel(): 91 seconds
With    AsParallel(): 23 seconds

使用Parallel.ForEach 和线程安全结果列表的另一种方式

System.Collections.Concurrent.ConcurrentBag<string> listResult = new System.Collections.Concurrent.ConcurrentBag<string>();
System.Threading.Tasks.Parallel.ForEach<string>(list2, str2 =>
{
    foreach (string str1 in list1)
    {
        if (str2.Contains(str1))
        {
            listResult.Add(str2);
            //break the loop if one match was found to avoid duplicates and improve performance
            break;
        }
    }
});

旁注:您必须首先遍历 list2 并在匹配之后 break;,否则您将添加项目两次:https://dotnetfiddle.net/VxoRUW

关于C# - 将 2 个列表与自定义元素进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50524582/

相关文章:

c# - 每个 SELECT 中的 WITH(nolock) - NHibernate

java - Groovy:list.pop() 不起作用

html - 如何使两个列表水平居中

java - Java中的倒直角三角形

c# - Entity Framework 6.1.3 从代码优先模型初始化现有但为空的数据库

c# - 双线性插值 - DirectX 与 GDI+

performance - 从列表列表中具有最大长度的每个子列表中删除项目的最快方法

java - 寻找更新多维数组的有效方法

string - 根据 Pandas 中其他两列的条件创建一个列

c# - 更改数据上下文后,依赖属性不会更新