如何检查相似项目的 2 个列表?

问题描述

我有 2 个列表(myItemsanotherItems),我想看看 myItems 上的项目是否在 anotherItems 上?

我目前正在使用 2 个 foreach 循环,但速度很慢,大约需要 1 分钟才能完成。

myItems = IEnumerable<SomeModel>

anotherItems = IEnumerable<String>

foreach (var item in myItems)
{
    foreach (var subItem in anotherItems)
    {
        var parsed = ParseItem(subItem,item.Id);
        if (parsed.Id != null && parsed.version != null)
        {
            if (item.Id.Equals(parsed.Id,StringComparison.OrdinalIgnoreCase))
            {
                myList.Add(new myModel
                {
                    Name = item.Name,Id = item.Id,Version = parsed.version
                });
                break;
            }
        }
    }
}

和 PareItem 是:

public static (string Id,string version) ParseItem(string line,string Id)
{
    line = Regex.Replace(line,"[ ]{2,}"," ",RegexOptions.IgnoreCase);
    line = Regex.Replace(line,$@".*(?=({Regex.Escape(Id)}))","",RegexOptions.IgnoreCase);
    var lines = line.Split(" ");
    if (lines.Count() == 2)
    {
        return (Id: lines[0],version: lines[1]);
    }
    return (Id: null,version: null);
}

我怎样才能更快地做到这一点?

解决方法

我建议使用以下解决方案,因为您的问题是您正在为 myItems 的每次迭代提取相同的项目:

  1. anotherItems = IEnumerable<String> 完整解析为 IEnumerable<SomeModel>,即使只能设置某些属性(我们知道在任何情况下都可以设置 Id)。

  2. 然后您可以使用 Intersect

public class SomeModel: IEquatable<SomeModel>
{
    public string Id { get; set; }

    public bool Equals(SomeModel other)
    {
        if (other is null)
            return false;

        return this.Id.Equals(other.Id,StringComparison.OrdinalIgnoreCase);
    }

    public override bool Equals(object obj) => Equals(obj as SomeModel);
    public override int GetHashCode() => (id).GetHashCode();
}

所以我希望你的代码看起来像:

// In this line iterate all items from the second list and extract.
myAnotherItemsList = ExtractSomeModelFromAnotherList(anotherItems);
var mergedList = myList.Intersect(myAnotherItemsList);