有没有办法在C#中比较两个列表?

6
我将通过以下方式比较两个列表:
var listOne = new List<int>{1,2,3,4,5};
var listTwo = new List<int>{1,2,3,4,5,7};
bool isEqual = false;

foreach (var item in listOne)
{
    if(listTwo.Contains(item))
    {
        isEqual = true;
    }
    else
    {
        isEqual = false;
        break;
    }
}

if(listOne.Count == listTwo.Count && isEqual == true)
{
    Console.WriteLine("Equal list");
}
else
{
    Console.WriteLine("Not Equal list");
}

有没有简单的方法来完成这个任务?

7
如果(listOne.Except(listTwo).Any()),则执行操作。LINQ - 比较两个列表 :) - Paritosh
2
你是否在乎项目的顺序?比如说,对你来说 {1,2} 和 {2,1} 是否相等? - Roee Gavirel
1
{1,2} = {2,1} 不重要 @RoeeGavirel - user2548991
1
@IITDU: 但是您接受的答案并没有忽略顺序。因此它与您的代码不同。 - Tim Schmelter
1
其实我不确定顺序是否重要。无论如何,我已经编辑过了。 - Atish Kumar Dipongkor
显示剩余3条评论
5个回答

22

非常容易的方法

    var listOne = new List<int>{1,2,3,4,5};
    var listTwo = new List<int>{1,2,3,4,5,7};

    if (listOne.SequenceEqual(listTwo))
            {
                Console.WriteLine("Equal list");
            }
            else
            {
                Console.WriteLine("Not Equal list");
            }

如果顺序无关紧要,那么解决方案将是

    var listOne = new List<int>{1,2,3,4,5};
    var listTwo = new List<int>{1,2,3,4,5,7};

     if (listOne.OrderBy(m => m).SequenceEqual(listTwo.OrderBy(m => m)))
        {
            Console.WriteLine("Equal list");
        }
        else
        {
            Console.WriteLine("Not Equal list");
        }

1
他没有提到他想知道两者是否具有相同的项目顺序。 - Tim Schmelter
2
这不正确!!{1, 2}{2, 1}应该返回true - Ahmed KRAIEM
1
@AhmedKRAIEM - OP没有直接指定,但他的代码似乎是这样的,是的。 - Corak
@AtishDipongkor:你最后的修改是低效的,甚至可能是错误的,因为它会修改两个集合。即使不需要,listOne.Sort() 也会改变项目的顺序。只需使用 Except 即可,它还更有效率,因为它使用了集合。 - Tim Schmelter
在您的单元测试中,您还需要使用CollectionAssert.AreEqual(list1, list2); - GodsCrimeScene
显示剩余6条评论

15

如果你对顺序没有要求,可以使用Except,它非常高效:

bool isEqual = !listOne.Except(listTwo).Any();
如果您想知道两个集合是否包含相同的项(仍然忽略顺序):
if (listOne.Count > listTwo.Count)
    isEqual = !listOne.Except(listTwo).Any();
else
    isEqual = !listTwo.Except(listOne).Any();

如果您想检查两个列表是否按相同的顺序包含相同的项:

bool isEqual = listOne.SequenceEqual(listTwo);

如果您正在使用自定义类型,则需要覆盖 EqualsGetHashCode,否则仅通过引用进行比较。


4

我认为最简单的方法是使用Enumerable.SequenceEqual方法。

通过使用其类型的默认相等比较器来比较元素,确定两个序列是否相等。

bool equal = listOne.SequenceEqual(listTwo);
SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>) 方法并行枚举两个源序列,并使用默认的 TSource 相等比较器 Default 比较相应元素。默认相等比较器 Default 用于比较实现了 IEqualityComparer<T> 泛型接口的类型的值。
正如 Tim 所指出的, 如果您的项目没有排序,使用 Except 方法会更好。例如;
bool equal = !listTwo.Except(listOne).Any();

但他不想知道项目的顺序是否也相同,至少他的旧代码没有检查这一点。 - Tim Schmelter
@TimSchmelter 谢谢 Tim,已更新。 - Soner Gönül

0
假设您不关心顺序,您可以使用OrderBySequenceEqual:

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (!listOne.OrderBy(x => x).SequenceEqual(listTwo.OrderBy(x => x)))
        return false;
}

或者 交集

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (listOne.Intersect(listTwo).Count() != listOne.Count)
        return false;

    return true;
}

或者 除了任何

public static bool ListsEquals(List<int> listOne, List<int> listTwo)
{
    if (listOne.Count != listTwo.Count)
        return false;

    if (!listOne.Except(listTwo).Any())
        return false;

    return true;
}

0

如果列表中的项目顺序很重要,您可以像许多人建议的那样使用SequenceEqual

如果顺序不重要,您应该在比较之前对列表进行排序,并且我建议在排序之前检查它们的数量,以避免对大小不同的列表进行排序和比较:

var listOne = new List<int>{1,2,3,4,5};
var listTwo = new List<int>{1,2,3,4,5,7};

var equal = (listOne.Count == listTwo.Count);

if (equal)
{
    listOne.Sort();
    listTwo.Sort();
    equal = listOne.SequenceEqual(listTwo)
}

if (equal)
{
     Console.WriteLine("Equal list");
}
else
{
     Console.WriteLine("Not Equal list");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接