C# 如何正确比较列表

C# 如何正确比较列表,c#,algorithm,list,optimization,comparison,C#,Algorithm,List,Optimization,Comparison,可能重复: 这是我的功能 public List<String[]> comparableListsAreTheSame(List<String> baseList, List<String> resultList, int type) { if (type == 1) { } List<String> baseListCopy = baseList; List<String

可能重复:

这是我的功能

    public List<String[]> comparableListsAreTheSame(List<String> baseList, List<String> resultList, int type)
    {
        if (type == 1) { }

        List<String> baseListCopy = baseList;
        List<String> resultListCopy = resultList;

        bool sameLength = (baseListCopy.Count == resultList.Count); // are 2 lists have the same length?

        List<String> Base = baseListCopy.Except(resultListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values 
        List<String> Result = resultListCopy.Except(baseListCopy, StringComparer.InvariantCultureIgnoreCase).ToList(); //Keep unique values 

        List<String[]> blocksComparisonSet1 = new List<String[]>(); //we add blocks based on list1; so we could output them to excel
        List<String[]> blocksComparisonSet2 = new List<String[]>(); //we add blocks based on list2; so we could output them to excel
        List<String[]> blocksComparisonFinal = new List<String[]>(); //we combine list1 and list

        //-----------------------------------------------------------------

        if (Result.Count > 0 || Base.Count > 0)
        {
            foreach (String resultLine in Result) //loop over all lines in list 1
            {
                bool found = false; //if element in base i
                String[] resultLineArray = resultLine.Split('*'); //get array from the string
                foreach (String baseLine in Base)
                {
                    String[] baseLineArray = baseLine.Split('*');
                    if (resultLineArray[0].Equals(baseLineArray[0]) && resultLineArray[1].Equals(baseLineArray[1]) && resultLineArray[2].Equals(baseLineArray[2]) && resultLineArray[3].Equals(baseLineArray[3]))
                    {
                        String[] NA = new String[2]; //keep results
                        NA[0] = baseLine; //[0] for base
                        NA[1] = resultLine; //[1] for result
                        blocksComparisonSet1.Add(NA);
                        found = true;
                    }
                }

                if (!found)
                {
                    String[] NA = new String[2]; //keep results
                    NA[0] = "N/A"; //[0] for base
                    NA[1] = resultLine; //[1] for result
                    blocksComparisonSet1.Add(NA);
                }
            }


            //-----------------------------------------------------------------
            foreach (String baseLine in Base) //loop over all lines in list 2
            {
                bool found = false; //if element in base i
                String[] baseLineArray = baseLine.Split('*'); //get array from the string
                foreach (String resultLine in Result)
                {
                    String[] resultLineArray = resultLine.Split('*');
                    if (resultLineArray[0].Equals(baseLineArray[0]) && resultLineArray[1].Equals(baseLineArray[1]) && resultLineArray[2].Equals(baseLineArray[2]) && resultLineArray[3].Equals(baseLineArray[3]))
                    {
                        String[] NA = new String[2]; //keep results
                        NA[0] = baseLine; //[0] for base
                        NA[1] = resultLine; //[1] for result
                        blocksComparisonSet2.Add(NA);
                        found = true;
                    }
                }

                if (!found)
                {
                    String[] NA = new String[2]; //keep results
                    NA[0] = baseLine; //[0] for base
                    NA[1] = "N/A"; //[1] for result
                    blocksComparisonSet2.Add(NA);
                }
            }
        }

        //-----------------------------------------------------------------
        if (blocksComparisonSet1.Any() || blocksComparisonSet2.Any()) //check if we have any values in out differences lists. if we do, merge them
        {
            blocksComparisonFinal.AddRange(blocksComparisonSet1); //add records from one list to final list
            blocksComparisonFinal.AddRange(blocksComparisonSet2); //add records from second list to final list
            HashSet<String[]> s = new HashSet<String[]>(blocksComparisonFinal);
            blocksComparisonFinal = s.ToList();
        }
        blocksComparisonFinal = blocksComparisonSet1.Union(blocksComparisonSet2, new ArrayEqualityComparer<string>()).ToList();
        return blocksComparisonFinal;
    }
public List compariablelistsarethesame(列表基本列表、列表结果列表、int类型)
{
如果(type==1){}
List baseListCopy=基本列表;
List resultListCopy=resultList;
bool sameLength=(baseListCopy.Count==resultList.Count);//两个列表的长度是否相同?
List Base=baseListCopy.Exception(resultListCopy,StringComparer.InvariantCultureIgnoreCase).ToList();//保留唯一值
List Result=resultListCopy.Exception(baseListCopy,StringComparer.InvariantCultureIgnoreCase).ToList();//保留唯一值
List blocksComparisonSet1=new List();//我们根据list1添加块;这样我们就可以将它们输出到excel
List blocksComparisonSet2=new List();//我们根据list2添加块,以便将它们输出到excel
列表块comparisonfinal=new List();//我们将list1和List结合起来
//-----------------------------------------------------------------
如果(Result.Count>0 | | Base.Count>0)
{
foreach(Result中的字符串resultLine)//循环列表1中的所有行
{
bool found=false;//基i中的if元素
String[]resultLineArray=resultLine.Split('*');//从字符串中获取数组
foreach(基线中的字符串基线)
{
字符串[]baseLineArray=baseLine.Split('*');
如果(resultLineArray[0]。等于(baseLineArray[0])&&resultLineArray[1]。等于(baseLineArray[1])&&resultLineArray[2]。等于(baseLineArray[2])&&resultLineArray[3]。等于(baseLineArray[3]))
{
String[]NA=新字符串[2];//保留结果
NA[0]=基线;//[0]表示基准
NA[1]=resultLine;//[1]表示结果
区块比较集1.添加(NA);
发现=真;
}
}
如果(!找到)
{
String[]NA=新字符串[2];//保留结果
NA[0]=“不适用”//[0]表示基础
NA[1]=resultLine;//[1]表示结果
区块比较集1.添加(NA);
}
}
//-----------------------------------------------------------------
foreach(基本中的字符串基线)//循环列表2中的所有行
{
bool found=false;//基i中的if元素
String[]baseLineArray=baseLine.Split('*');//从字符串中获取数组
foreach(结果中的字符串结果行)
{
字符串[]resultLineArray=resultLine.Split('*');
如果(resultLineArray[0]。等于(baseLineArray[0])&&resultLineArray[1]。等于(baseLineArray[1])&&resultLineArray[2]。等于(baseLineArray[2])&&resultLineArray[3]。等于(baseLineArray[3]))
{
String[]NA=新字符串[2];//保留结果
NA[0]=基线;//[0]表示基准
NA[1]=resultLine;//[1]表示结果
区块比较集合2.添加(NA);
发现=真;
}
}
如果(!找到)
{
String[]NA=新字符串[2];//保留结果
NA[0]=基线;//[0]表示基准
NA[1]=“不适用”/[1]表示结果
区块比较集合2.添加(NA);
}
}
}
//-----------------------------------------------------------------
if(blocksComparisonSet1.Any()| | blocksComparisonSet2.Any())//检查out差异列表中是否有值。如果有,则合并它们
{
blocksComparisonFinal.AddRange(blocksComparisonSet1);//将记录从一个列表添加到最终列表
blocksComparisonFinal.AddRange(blocksComparisonSet2);//将记录从第二个列表添加到最终列表
HashSet s=新的HashSet(blocksComparisonFinal);
blocksComparisonFinal=s.ToList();
}
blocksComparisonFinal=blocksComparisonSet1.Union(blocksComparisonSet2,新的ArrayEqualityComparer()).ToList();
返回块比较最终结果;
}

我对C#和编程基本上是新手,我做了多个循环,并以非常棒的barabric方式匹配了所有东西。我能以更专业的方式处理它,并且做得更干净、更恰当吗?

我有几点意见

最内层的foreach循环可以替换为List.Contains方法。通过将其拆分为一个数组,然后在可以直接比较字符串的情况下在该数组中循环,增加了大量开销

此外,在列表2中所有行上循环的第二个循环只需要跟踪未命中,而不是命中。第一个循环查找(1&2)和(1&2)中的项目,因此第二个循环只需要查找(不是1&2)中的项目(如果有意义的话)。这也使得您不必在最后将命中/未命中列表合并在一起。

如果您倾向于先对列表进行排序,您可以更高效、更干净地进行排序


我希望这能有所帮助。

如果您正在检查listA和listB是否具有相同的元素,则可以使用此扩展方法:

public static IEnumerable<TSource> Intersect<TSource>
(
    this IEnumerable<TSource> first,
    IEnumerable<TSource> second,
    Func<TSource, TSource, bool> comparer
)
{
    return first.Intersect(second, new LambdaComparer<TSource>(comparer));
}

定义列表“相等”的含义。可能更适合codereview.stackexchange.com的
类型
参数是什么?一般来说,您可以创建一个实现
IEqualityComparer
的类和/或一个实现
IEqualityComparer
的类来大大简化您的代码。看起来您要做的不仅仅是确定这两个列表是否相等……您能再解释一下您要完成的任务吗?
var compared = listA.Intersect(listB, (a, b) => a == b);
if(compared.Count() == listA.Count())
   // they are the same
else
   // they are not