使用类列表中的数据更新类列表

本文关键字:列表 数据 更新 | 更新日期: 2023-09-27 17:55:39

我有一个类:

public class DataMember {
    public string ID{ get; set; }
    public List<string> Versions { get; set; }
}

还有一类:

public class MasterDataMember {
    public string ID { get; set; }
    public List<string> FoundVersions { get; set; }
}

我将两组数据存储在缓存中,如下所示:

List<DataMember> datamembers
List<MasterDataMember> masterdatamembers

最初构建时,MasterDataMember 是部分"版本"的列表。这些版本需要确认并在数据成员列表中找到。

如何使用数据成员中找到的已确认版本更新主数据成员?(此代码块未经测试,但它说明了我正在尝试做什么)

foreach (MasterDataMember item in masterdatamembers) {
    List<string> confirmedvers = new List<string>();
    foreach(string rawver in item.FoundVersions ){
        foreach(DataMember checkitem in datamembers){
            foreach (string confirmedver in checkitem.Versions) {
                if (rawver.Contains(confirmedver)) {
                    confirmedvers.Add(confirmedver);
                }
            }
        }
    }
    item.FoundVersions = vers;
}

是否有一个 LINQ 可以更轻松、更快地完成此操作(我已经尝试了很多想法、迭代)?

速度是这里的关键,因为这两个列表都可以有数百到数千个长度。

提前谢谢你!

使用类列表中的数据更新类列表

foreach (MasterDataMember item in masterdatamembers) {
    IEnumerable<string> confirmedvers = item.FoundVersions.Where(rawver => rawver.Any(confirmedver => datamembers.Any(checkitem => checkitem.Versions.Contains(rawver)));
}

神圣的废话兄弟,这对我来说就像地狱一样令人困惑!

不过很棒的心灵实验!

如果由于列表很大,速度确实是您的主要关注点,那么您需要使用哈希表结构。 使用 LINQ 很流畅,但不一定会让您更快(或更清晰)。您真正需要的是使用正确的集合类型。

对以下代码所做的假设:

  • datamembers缓存不能有重复的DataMember条目(其中多个条目具有相同的 ID)。
  • masterdatamembers缓存不能有重复的MasterDataMember条目(其中多个条目具有相同的 ID)。
  • DataMemberMasterDataMember中,VersionsFoundVersions列表不能有重复的版本条目。

算法说明

我仍然觉得你的代码块不能完全反映你的意图。 不幸的是,结果,我认为你得到了错误的答案。

这是我遵循的算法,基于尝试解释您的预期结果:

对于每个主数据成员,通过仅将版本保留在列表中来更新其FoundVersions集(或列表),该版本也可以在匹配的数据成员的Versions集(或列表)中找到。 如果没有找到匹配的数据成员,那么我假设您希望清空主数据成员FoundVersions集合(或列表),因为无法确认任何版本。

实现

请注意,我用Dictionary<K, V>HashSet<T>替换了List<T>的一些用法,因为它会提高性能。 当然,我假设你的名单可以像你说的那样变得很大。 否则,性能将类似于简单列表。

您的 2 个类,(注意类型的变化):

public class DataMember
{
    public string ID { get; set; }
    public HashSet<string> Versions { get; set; } // using hashset is faster here.
}
public class MasterDataMember
{
    public string ID { get; set; }
    public HashSet<string> FoundVersions { get; set; } // used HashSet for consistency, but for the purposes of the algorithm, a List can still be used here if you want.
}

您的缓存数据(请注意对字典的更改):

Dictionary<string, DataMember> datamembers; // using a Dictionary here, where your key is the DataMember's ID, is your fastest option.
List<MasterDataMember> masterdatamembers; // this can stay as a list if you want.

最后,工作在这里完成:

foreach (var masterDataMember in masterdatamembers)
{
    DataMember dataMember;
    if (datamembers.TryGetValue(masterDataMember.ID, out dataMember))
    {
        HashSet<string> newSet = new HashSet<string>();
        foreach (var version in masterDataMember.FoundVersions)
        {
            if (dataMember.Versions.Contains(version))
            {
                newSet.Add(version);
            }
        }
        masterDataMember.FoundVersions = newSet;
    }
    else
    {
        masterDataMember.FoundVersions.Clear();
    }
}

您的代码在 Linq 中如下所示

masterDataMembers.ForEach(q=>q.FoundVersions = (from rawver in q.FoundVersions from checkitem in dataMembers from confirmedver in checkitem.Versions where rawver.Contains(confirmedver) select confirmedver).ToList());