将一对值与一组值对C#进行比较

时间:2017-01-27 17:48:28

标签: c# arrays

我有一对值int x和int y,想看看这对值是否出现在一对值的二维数组中。

通常,我现在拥有的是:

if ((x == 5 && y == 2) || (x == 6 && y == 1) || ETC)
    return true;

由于有很多可能需要返回true,我认为创建一个包含这些值对的数组会更容易,看看x和y是否一起出现在该数组中:

int[,] arrayOfPairs = new int[,]
    {
        {5, 2},
        {6, 1},
    };

我知道在C ++中我们可以使用std :: find来做到这一点但不知道它是否可能在C#中。

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

尝试使用Tuple<int, int>数组...例如:

Tuple<int, int>[] pairs = new Tuple<int, int>[]
{
    Tuple.Create(5, 2),
    Tuple.Create(6, 1),
};

然后你可以确定一个元素是否存在:

if (Array.IndexOf(pairs, Tuple.Create(3, 4)) != -1)
{
    // element exists.
}

有很多方法可以用LINQ做这个:

if (pairs.Any(x => x == Tuple.Create(3, 4)))
{
    // element exists
}

Per @ Martheen的建议,以下是如何使用HashSet实现。

HashSet<Tuple<int, int>> pairs = new HashSet<Tuple<int, int>>()
{
    Tuple.Create(5, 2),
    Tuple.Create(6, 1),
};

可以使用如下:

if (pairs.Contains(Tuple.Create(3, 4)))
{
    // element exists
}

由于您使用的是Unity,因此可以用Tuple替换Vector2。然后我的第一个方法将起作用。

此外,如果您希望获得使用HashSet但无法访问该集合的速度优势,那么您可以使用常规旧版Hashtable

// initialize pairs
Hashtable pairs = new Hashtable().
pairs.Add(new Vector2(5F, 2F), true);
pairs.Add(new Vector2(6F, 1F), true);

// check for existence
if (pairs.ContainsKey(new Vector2(3F, 4F))
{
    // element exists
}

答案 1 :(得分:3)

请注意int[,] arrayOfPairs是一个多维数组。它不是一对数组,它甚至不是一个数组数组。在访问项目时,您将需要两个索引,这将基本上混淆这两个数字作为其对的一部分的关系。

相反,您应该使用实际的数组数组:int[][]。这样,例如该数组的第一个元素是该对的成员数组。当然,这种结构不会强制执行任何维度,因此您无法确定该数组的元素是否为2元素数组。

int[][] arrayOfPairs = new int[][]
{
    new int[] { 5, 2 },
    new int[] { 6, 1 },
};

更好的解决方案是使用能够实际强制执行完整对的内容,即恰好2个元素。您可以使用Tuple类型,或者甚至为此目的提出您自己的类型。 Tuple类型已经附带了一个很好的相等比较器,因此您可以很好地将它用于您的目的。您甚至可以将它们放入一组以进行快速成员资格测试:

var pairs = new HashSet<Tuple<int, int>>()
{
    Tuple.Create(5, 2),
    Tuple.Create(6, 1)
};

Console.WriteLine(pairs.Contains(Tuple.Create(5, 3))); // false
Console.WriteLine(pairs.Contains(Tuple.Create(5, 2))); // true

最后一点说明:你原来的状况并没有多大意义:

if ((x == 5 && y == 2) && (x == 6 && y == 1) && ETC)

x, y无法同时成为5, 26, 1,因此条件总是错误的。

如果必须使用没有元组的.NET 2.0,您只需为此创建自己的类型:

public struct Pair
{
    public int X { get; set; }
    public int Y { get; set; }

    public Pair(int x, int y)
    {
        X = x;
        Y = y;
    }

    public override bool Equals(object other)
    {
        var otherPair = other as Pair?;
        return otherPair != null && otherPair.Value.X == X && otherPair.Value.Y == Y;
    }

    public override int GetHashCode()
    {
        return (17 + X.GetHashCode()) * 23 + Y.GetHashCode();
    }
}

然后你的例子看起来像这样:

var pairs = new HashSet<Pair>()
{
    new Pair(5, 2),
    new Pair(6, 1)
};

Console.WriteLine(pairs.Contains(new Pair(5, 3))); // false
Console.WriteLine(pairs.Contains(new Pair(5, 2))); // true

如果你想把它保存为一个数组数组,你也可以编写自己的Enumerable.Contains方法(LINQ附带.NET 3.5):

public bool Contains(int[][] array, int[] item)
{
    foreach (int[] elem in array)
    {
        if (elem.Length != 2)
            throw new ArgumentException("Array element length should be exactly 2", "array");

        if (elem[0] == item[0] && elem[1] == item[1])
            return true;
    }

    return false;
}

像这样使用:

Console.WriteLine(Contains(arrayOfPairs, new int[] { 5, 2 })); // true
Console.WriteLine(Contains(arrayOfPairs, new int[] { 5, 1 })); // false

答案 2 :(得分:0)

尝试使用Objects进行操作。

class pair
{
     int x;
     int y;
}

将所有配对对象存储在List中。 当你比较任何价值时。只需遍历对象列表,查看是否有任何对象具有相同的x和y坐标。

如果等同于对象,也许你可能必须重载Equals()和GetHashCode()。

答案 3 :(得分:-2)

有些人认为LINQ查询语法最容易阅读:

    static void Main(string[] args)
    {
        int[][] arrayOfPairs = new int[][]
            {
                new int[] { 5, 2 },
                new int[] { 6, 1 },
            };

        System.Console.WriteLine(IsMatch(1, 3, arrayOfPairs));
        System.Console.WriteLine(IsMatch(5, 2, arrayOfPairs));
        System.Console.ReadKey();
    }

    static bool IsMatch(int x, int y, int[][] pairs)
    {
        var results = 
            from pair in pairs
            where pair[0] == x && pair[1] == y
            select pair;

        return results.Any();
    }

输出: 假 真