我有一个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;
}
我希望能快一点.
我有一个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有多个字符串,则可以考虑以下选项:
Lookup<TKey,TElement>
:表示键的集合,每个键都映射到一个或多个值.
然后搜索匹配元素的集合
Id
到HashSet<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;
}
}
GetHashcode
和Equals
来构建相应的哈希表(基本思想是一样的-你需要"常量"查找):var hashSet = anotherList
.Select(d => (d.Id, d.Line))
.ToHashSet();
foreach(var dto in List)
{
if (hashSet.Contains((dto.Id, dto.Line)))
{
continue;
}
}
阅读更多:
Dictionary<TKey,TValue>
Dictionary<TKey,TValue>
泛型类提供从一组键到一组值的映射.字典中的每个新增项都由一个值及其关联键组成.使用键检索值非常快,接近O(1),因为Dictionary<TKey,TValue>
类是作为哈希表实现的.