How to properly compare lists

Go To StackoverFlow.com

0

Possible Duplicate:
Compare two Lists for differences

this is myfunction

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

I am new to C# and programming in general and I did multiple loops and matched everything in pretty barabric way. Can I approach it more professional way and do it cleaner and PROPER?

2012-04-03 21:07
by Andrew
Define what you mean by list 'equality' - Kendall Frey 2012-04-03 21:15
Probably better suited to codereview.stackexchange.co - phoog 2012-04-03 21:15
What's the type parameter for? In general, you could create a class that implements IEqualityComparer<List<string[]>> and/or a class that implements IEqualityComparer<string[]> to simplify your code considerably - phoog 2012-04-03 21:18
It seems like you're trying to do a lot more than just determine if the two lists are equal...could you explain a little more about what you are trying to accomplish - Ethan Brown 2012-04-03 21:20


1

If you are checking if listA and listB have the same elements you can use this extension method:

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

Which uses the LambdaComparer class.

You can then compare them in this manner:

var compared = listA.Intersect(listB, (a, b) => a == b);
if(compared.Count() == listA.Count())
   // they are the same
else
   // they are not
2012-04-03 21:50
by Chuck Savage


1

I have just a couple of comments.

Your innermost foreach loops can be replaced with List.Contains methods. You're adding a bunch of overhead by splitting it into an array and then looping through that array when you can just compare the strings directly. http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

Also, your second loop that is looping over all of the lines in list 2 only needs to keep track of the misses, not the hits. The first loop finds the items in (1 & 2) and (1 & not 2) so the second loop is only needed to find the items that are (not 1 & 2) if that makes sense. That will also make it so you won't have to merge the hit/miss lists together at the end.

If you were inclined to sort the lists first, you can do this much more efficiently and cleanly.

I hope this can help.

2012-04-03 21:37
by user1308985