0

我试图找到在 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
        }
4

1 回答 1

0

我无法理解您的班级结构,因此我将尝试以更通用的方式回答您的问题。

首先让我了解您到底需要什么。

假设您有 3 个列表,其中包含 3 个不同的类。因此,您有列表 L1、L2 和 L3,其中分别是 C1、C2 和 C3 类。

您需要一个列表说 L4 和另一个(或上面的一个?)类说 C4 并且这个列表不应该包含基于所有 3 个类中的某些公共属性的重复项。

我对这个问题的看法是以下代码。我不太确定这是否有效,但它确实有效。它也不是通用的,即适用于任何数量的列表,任何一组实现某个接口的类。试一试,让我知道,从性能方面来说,它是否会造成问题或以任何其他方式造成问题。

我希望这有帮助。

问候,

萨马尔

    private void btnCompare_Click(object sender, EventArgs e)
    {
        //Creating dummy data for testing
        List<C1> L1 = new List<C1>() { new C1() { ID = 1 }, new C1() { ID = 4 } };
        List<C2> L2 = new List<C2>() { new C2() { ID = 1 }, new C2() { ID = 2 } };
        List<C3> L3 = new List<C3>() { new C3() { ID = 1 }, new C3() { ID = 2 }, new C3() { ID = 3 } };

        //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 });

        //Add only those objects from L2 which are not part of L1
        L4.AddRange(from l22 in L2
                    where !(from l4 in L4 join l2 in L2 on l4.ID equals l2.ID select new { ID = l4.ID }).Any(p => p.ID == l22.ID) 
                    select new C4() { ID = l22.ID });

        //Add only those objects from L3 which are not part of L1 and L2
        L4.AddRange(from l33 in L3
                    where !(from l4 in L4 join l3 in L3 on l4.ID equals l3.ID select new { ID = l4.ID }).Any(p => p.ID == l33.ID)
                    select new C4() { ID = l33.ID });

        //L4 will now contain all IDs without duplicates
    }

    class C1
    {
        public int ID { get; set; }

        //will contain other properties
    }

    class C2
    {
        public int ID { get; set; }

        //will contain other properties
    }

    class C3
    {
        public int ID { get; set; }

        //will contain other properties
    }

    class C4
    {
        public int ID { get; set; }

        //will contain other properties or maybe a combination of all the properties of C1, C2 and C3
    }
于 2013-09-02T07:51:18.023 回答