我试图找到在 C# 中比较 3 个列表的最佳方法,然后将结果合并到一个 csv 文件中。我的代码需要花费大量时间来处理我的数据,我想改进这一点。
我目前所做的是使用 LINQ 一次比较 2 个列表,将每个比较的结果保存到一个临时列表中,然后在将其保存为 csv 文件之前将其合并。
我的列表比较的一个示例:
foreach (RemedyAsset remedyAsset in RemedyAssetsList)
{
MIAsset tempMIAsset = null;
tempMIAsset = MIAssetsList.FirstOrDefault(m => m.CIName.ToUpper() == remedyAsset.CIName.ToUpper());
if (tempMIAsset == null)
{
TempAssets.Add(new TempAsset
{
Asset = remedyAsset.CIName,
LastMiActivity = string.Empty,
RemedyStatus = remedyAsset.Status,
InMI = false,
InRemedy = true
});
}
else
{
TempAssets.Add(new TempAsset
{
Asset = remedyAsset.CIName,
LastMiActivity = tempMIAsset.LastActiveTime,
RemedyStatus = remedyAsset.Status,
InMI = true,
InRemedy = true
});
}
}
我的列表源自 3 个不同的 IT 系统(BMC Remedy、Active Directory、Checkpoint),它们有一个共同变量:资产编号。
我的列表如下所示:
-(List1)RemedyReport:资产编号 - 补救状态。
-(List2)ADReport:资产编号-上次登录时间-上次密码更改。
-(List3)MIReport:资产编号 - 最后一次服务器联系。
当我比较列表时,我还会检查列表中是否不存在资产编号,这也需要显示在输出 csv 文件中。然后,我需要从存在匹配资产编号的列表中合并数据,输出将如下所示:
资产编号 - 在补救措施中 - 在 MI - 在 AD 中 - 上次服务器联系 - 上次登录 - 上次密码更改
比较 3 个列表的最佳方法是什么?
比较 3 个或更多列表时是否有任何最佳实践?
这是我在这里的第一篇文章,如果我做错了什么,请告诉我。
基于 Samar 建议的解决方案
我改编了 Samar 的建议,满足了我的需求。性能从 9 分钟提高到不到 2 分钟。
public void compare()
{
//Creating dummy data for testing
List<C1> L1 = new List<C1>() { new C1() { ID = 1, classC1="test1" }, new C1() { ID = 4, classC1="test1" } };
List<C2> L2 = new List<C2>() { new C2() { ID = 1, classC2="test2" }, new C2() { ID = 2, classC2="test2" } };
List<C3> L3 = new List<C3>() { new C3() { ID = 1 }, new C3() { ID = 2, classC3="test3" }, new C3() { ID = 3, classC3="test3" } };
//Creating new list which will contain all the objects without duplicates based on ID column
List<C4> L4 = new List<C4>();
//Firstly add all the objects from L1
L4.AddRange(from l1 in L1 select new C4() { ID = l1.ID, classC1=l1.classC1 });
//Add only those objects from L3 which are not part of L1
L4.AddRange(from l22 in L2
where !(L4.Where(l44 => l44.ID == l22.ID)
.Select(l44 => { l44.classC2 = l22.classC2; return l44; }).Any(p => p.ID == l22.ID))
select new C4() { ID = l22.ID, classC2 = l22.classC2 });
//Add only those objects from L3 which are not part of L1 and L2
L4.AddRange(from l33 in L3
where !(L4.Where(l44 => l44.ID == l33.ID)
.Select(l44 => { l44.classC3 = l33.classC3; return l44; }).Any(p => p.ID == l33.ID))
select new C4() { ID = l33.ID, classC3 = l33.classC3 });
//L4 will now contain all IDs without duplicates
}
class C1
{
public int ID { get; set; }
public string classC1 { get; set; }
//will contain other properties
}
class C2
{
public int ID { get; set; }
public string classC2 { get; set; }
//will contain other properties
}
class C3
{
public int ID { get; set; }
public string classC3 { get; set; }
//will contain other properties
}
class C4
{
public int ID { get; set; }
public string classC1 { get; set; }
public string classC2 { get; set; }
public string classC3 { get; set; }
//will contain other properties or maybe a combination of all the properties of C1, C2 and C3
}