比较两个数组相等的更好方法?

时间:2013-07-26 14:14:43

标签: c# .net unit-testing

目标

确保两个字符串数组相同,更具体地说,长度相同并包含相同的项目。

CODE

所以,在我的单元测试中,我有以下代码:

var sut = new PersonValid();
var expected = new string[] { "Id", "FirstName", "LastName" };

Assert.AreEqual(expected.Length, sut.DataFields.Count);
Assert.AreEqual(0, sut.DataFields.Where(df => !expected.Contains(df)).Count());

它有效,但它真的不那么优雅。不存在更好的方法吗?

4 个答案:

答案 0 :(得分:5)

如果您需要序列相同,那么:

您可以使用Enumerable.SequenceEqual

var IsEqual = sut.DataFields.SequenceEqual(expected);

答案 1 :(得分:1)

如果订单很重要

使用Enumerable.SequenceEqual

以上链接中的示例:

class Pet
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public static void SequenceEqualEx1()
{
    Pet pet1 = new Pet { Name = "Turbo", Age = 2 };
    Pet pet2 = new Pet { Name = "Peanut", Age = 8 };

    // Create two lists of pets.
    List<Pet> pets1 = new List<Pet> { pet1, pet2 };
    List<Pet> pets2 = new List<Pet> { pet1, pet2 };

    bool equal = pets1.SequenceEqual(pets2);

    Console.WriteLine(
        "The lists {0} equal.",
        equal ? "are" : "are not");
}

如果订单不重要

首先订购enumerables,然后使用上面的Enumerable.SequenceEqual。

答案 2 :(得分:1)

您的问题未完全说明。你没有为数组定义“相等”。

特别是,订单有关系吗?项目计数怎么样?

如果订单确实很重要:

return first.SequenceEquals(second);

如果计数重要:

return !first.Except(second).Union(second.Except(first)).Any();

如果订单重要且计算执行重要,则需要采用以下方法:

public bool Compare<T>(T[] first, T[] second) {
    var firstItemCounts = first.GroupBy(x => x)
                               .ToDictionary(g => g.Key, g => g.Count());
    var secondItemCounts = second.GroupBy(x => x)
                                 .ToDictionary(g => g.Key, g => g.Count());
    foreach(var key in firstItemCounts.Keys.Union(secondItemCounts.Keys)) {
        if(!firstItemCounts.ContainsKey(key) ||
               !secondItemCounts.ContainsKey(key)
        ) {
            return false;
        }
        if(firstItemCounts[key] != secondItemCounts[key]) {
            return false;
        }
    }
    return true;
}

答案 3 :(得分:1)

使用课程CollectionAssert

var sut = new PersonValid();
var expected = new string[] { "Id", "FirstName", "LastName" };    
CollectionAssert.AreEqual(expected, sut.DataFields)