如何检查List<;int[]>;包含一个与另一个int[]存储相同值的int[]元素

本文关键字:int 另一个 存储 元素 gt List 检查 lt 何检查 包含一 | 更新日期: 2023-09-27 18:19:26

假设我有一个整数数组列表和一个整数阵列:

List<int[]> MyListOfIntArrays = new List<int[]>
                                 {
                                      new int[1] {0},
                                      new int[2] {0,1},
                                      new int[2] {1,0}
                                 };
int[] MyArray = new int[]{1, 0};

我想知道如何检查MyListOfIntArrays中是否有一个元素存储了与MyArray相同的值。在这种情况下,答案应该是:"是"(MyListOfIntArrays的第三个元素存储的值与MyArray相同)。

我的尝试:

if (MyListOfIntArrays.Contains(MyArray) == true)
    Console.WriteLine("Yes");
if (MyListOfIntArrays.Contains(MyArray) == false)
    Console.WriteLine("No");

总是返回no。我是C#的新手,我的猜测是方法"Contains"在这里检查引用,而不是值。有人能帮我解决这个问题吗?

如何检查List<;int[]>;包含一个与另一个int[]存储相同值的int[]元素

这是有效的:

var contains = MyListOfIntArrays.Any(arr => arr.GetType() == MyArray.GetType() && arr.SequenceEqual(MyArray));

编辑:

正如两条评论所建议的,它可以缩短为

var contains = MyListOfIntArrays.Any(arr => arr.SequenceEqual(MyArray));

您可以使用FindIndexSequenceEqual

当ever谓词返回true时,FindIndex将返回给定数组(MyListOfIntArrays)的索引。如果找不到任何东西,它将返回-1。

SequenceEqual将逐个元素检查数组的相等性,而不是像Contains通常那样检查引用(因为它使用默认比较器,数组由引用检查)。另一种方法是使用Servy显示的自定义比较器。

if (MyListOfIntArrays.FindIndex(x => x.SequenceEqual(MyArray)) != -1) // if != -1 means we found array!
    Console.WriteLine("Yes");
else
    Console.WriteLine("No");

如果你不需要索引,你可能想让它变得简单。Any只会给出一个布尔值,正如Asad Saeeduddin:所评论的那样

if(MyListOfIntArrays.Any(MyArray.SequenceEqual))
    Console.WriteLine("Yes");
else
    Console.WriteLine("No");

数组为自己定义的等式仅检查数组是否引用同一对象;它不会检查数组的内容是否相同。如果你想根据它们的值进行比较,你需要创建一个比较器来比较数组的值:

public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    private IEqualityComparer<T> comparer;
    public SequenceComparer(IEqualityComparer<T> comparer = null)
    {
        comparer = comparer ?? EqualityComparer<T>.Default;
    }
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        return x.SequenceEqual(y, comparer);
    }
    public int GetHashCode(IEnumerable<T> sequence)
    {
        unchecked
        {
            int hash = 19;
            foreach (var item in sequence)
                hash = hash * 79 + comparer.GetHashCode(item);
            return hash;
        }
    }
}

这可以让你写:

if (MyListOfIntArrays.Contains(MyArray, new SequenceComparer<int>()))
    Console.WriteLine("Yes");
else
    Console.WriteLine("No");

.Contains将不起作用,因为数组是引用类型,并且只有在将MyArray专门指向的数组而不是相同的数组添加到列表中时,才会得到true。

虽然您可以使用与所有数组的元素比较来解决问题,但我觉得更好的解决方案是使用集合而不是数组。如果你有一个ISet<ISet<int>>而不是List<int[]>,你可以非常容易有效地检查给定的ISet<int>是否是成员。