Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asserting two List<List<T>> Are Equivalent to Each Other

Tags:

c#

nunit

To make sure that two lists are the same, in nunit, we can use CollectionAssert.AreEquivalent to check that these two lists contain the same elements ( orders not important).

But how to check whether two List<List<T>> are equivalent? The idea is that if one List<T> has the same elements as the other List<T> ( again, order not important) then they are equal.

like image 642
Graviton Avatar asked Aug 17 '10 13:08

Graviton


People also ask

How do you assert two lists are equal?

Using Counter() , we usually are able to get frequency of each element in list, checking for it, for both the list, we can check if two lists are identical or not.

How do you assert two lists in JUnit?

Using JUnit We can use the logic below to compare the equality of two lists using the assertTrue and assertFalse methods. In this first test, the size of both lists is compared before we check if the elements in both lists are the same. As both of these conditions return true, our test will pass.

How do you assert a list in Java?

In tests, we need to add assertions to make sure that a result is the expected result. For this, we can make use of the AssertJ assertion library. To assert that an object equals the expected object, we can simply write assertThat(actualObject).

Which method is used to check 2 values are same in JUnit?

“assertSame()” functionality is to check that the two objects refer to the same object. Since string3=”test” and string4=”test” means both string3 and string4 are of the same type so assertSame(string3, string4) will return true. assertNotSame(string1, string3);


2 Answers

You do have to loop through them to be sure that they are equivalent, but with some important shortcuts:

  1. If they are actually the same instance (and in real code this often comes up), then ReferenceEquals(x, y) will return true. Otherwise it won't. If ReferenceEquals returns true, then they are equivalent.

  2. If one is null and the other isn't, then obviously they aren't equal (if they are both null you'll have caught that above with ReferenceEquals). You'll need to test for null anyway for safety, so you've another short-cut in many cases.

  3. If they are of different sizes then (for most definitions of equivalence, there are exceptions) they are not equal. Return false immediately.

  4. The moment you've found a mismatch, you can return false without continuing to check.

  5. It will be faster to compare them if they are already sorted. If you can keep them sorted, or failing that keep track of whether they are sorted or not and then sort only when needed, you can massively speed things up. (Note though that many sorting algorithms have their worse-case behaviour when needlessly sorting a list that is already sorted).

like image 98
Jon Hanna Avatar answered Oct 22 '22 01:10

Jon Hanna


Here's an attempt, not tested. If each inner list contains m elements, and the outer list-list contains n lists, I believe the complexity is O (n^2 x m), but I might be wrong. Assumptions:

  1. T does not implement IComparable or any such interface that allows sorting.
  2. Ordering is irrelevant to equality for both the List<List<T>>s and the composing List<T> objects.

--

public static bool ListListsAreEqual<T>(List<List<T>> listlist1, List<List<T>> listlist2)
{
    if (listlist1.Count != listlist2.Count)
        return false;

    var listList2Clone = listlist2.ToList();

    foreach (var list1 in listlist1)
    {
        var indexOfMatchInList2 = listList2Clone
                   .FindIndex(list2 => ListsArePermutations(list1, list2));

        if (indexOfMatchInList2 == -1)
            return false;

        listList2Clone.RemoveAt(indexOfMatchInList2);
    }

    return true;
}

private static bool ListsArePermutations<T>(List<T> list1, List<T> list2)
{
    return list1.Count == list2.Count && new HashSet<T>(list1).SetEquals(list2);
}
like image 40
Ani Avatar answered Oct 22 '22 01:10

Ani