我有一个FORACH,在这个FORACH中我遍历一个列表,在这个FORACH中我有一个条件来判断在另一个有20万行的列表中是否有特定的信息是字符串.

我想快点做.

  foreach(var dto in List){
    // the problem is here
    if(anotherList.Any(d => d.id == dto.id && d.line.equals(dto.line))) 
          continue;
    }

我希望能快一点.

推荐答案

Any的复杂度为O(n),其中n是集合中的元素数(anotherList),因此代码的总体复杂度为O(m*n),其中m是List中的元素数.如果id是唯一,那么您可以创建查找字典,它在一般情况下应该具有恒定的查找时间,并执行如下操作:

var dict = anotherList
  .ToDictionary(d => d.Id);

foreach(var dto in List)
{
    if (dict.TryGetValue(dto.Id, out var val) && val.line.equals(dto.line))
    {
        continue;
    }
}

这应该会将复杂性降低到O(m+n).

如果每个ID有多个字符串,则可以考虑以下选项:

  1. 如果每个ID的字符串不多,请使用Lookup<TKey,TElement>:

表示键的集合,每个键都映射到一个或多个值.

然后搜索匹配元素的集合

  1. 构建从IdHashSet<strings>的词典,并判断哈希集:
var dictOfSets = anotherList
    .GroupBy(d => d.Id)
    .ToDictionary(gr => gr.Key, gr => gr.Select(d => d.Line).ToHashSet());

foreach(var dto in List)
{
    if (dictOfSets.TryGetValue(dto.Id, out var val) && val.Contains(dto.Line))
    {
        continue;
    }
}
  1. 试着利用value tuples和它生成的GetHashcodeEquals来构建相应的哈希表(基本思想是一样的-你需要"常量"查找):
var hashSet = anotherList
    .Select(d => (d.Id, d.Line))
    .ToHashSet();

foreach(var dto in List)
{
    if (hashSet.Contains((dto.Id, dto.Line)))
    {
        continue;
    }
}

阅读更多:

Csharp相关问答推荐

由于POST中的应用程序/JWT,出现不支持的内容类型异常

将字节转换为 struct 并返回

如何将DotNet Watch与发布配置和传递给应用程序的参数一起使用?

是否有必要在ASP.NET Core中注册可传递依赖项?

带有列表参数的表达式树

如何防止Visual Studio断点以红色突出显示到整行?

为值对象编写自定义JsonConverter

当try 测试具有协变返回类型的抽象属性时,类似功能引发System.ArgumentException

Azure函数正在返回值列表,但该列表在Chrome中显示为空

Visual Studio如何使用当前的框架?

如何使用.NET 8.0中新的CompositeFormat类?

最小API定义的Swagger标头参数

实体框架允许您具有筛选的属性吗?

将文本从剪贴板粘贴到RichTextBox时,新文本不会在RichTextBox ForeColor中着色

SendInput无法在C#中正确模拟键盘

无法将';无效';转换为';bool';

接口中的泛型基类和非泛型子类存在问题

一些C#11&;12练习失败

如何指定使用 Auth0 和 Blazor WASM 成功登录后返回的 URL?

当用户在 Windows App SDK (WinUI 3) 中调整大小时,如何保持 AppWindow 的 16:9 宽高比?