我有一对值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#中。
感谢您的帮助!
答案 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, 2
和6, 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();
}
输出: 假 真