因此,我正在尝试在列表中搜索 int[2] 的索引,但是运气不佳。
以下是我一直在使用的代码:
var coordinates = new List<int[]>();
coordinates.Add(new int[] { 1, 2 });
coordinates.Add(new int[] { 3, 4 });
coordinates.Add(new int[] { 5, 6 });
//foreach (int[] array in coordinates)
//{
// Console.WriteLine(string.Join(", ", array));
//}
coordinates.AddRange(new int[3][] { [7, 8], [9, 10], [11, 12] });
foreach (int[] array in coordinates)
{
Console.WriteLine(string.Join(", ", array));
}
//var index = coordinates.IndexOf([3,4]);
var index = coordinates.IndexOf(new int[] { 3, 4 });
Console.WriteLine(index);
上述两行 IndexOf 都返回了 -1 的值,因此我认为我的语法是错误的(或者我使用了错误的工具,这也是可能的)。有什么建议吗?
C# 中的数组是引用类型。当底层对象相同时,它们彼此相等。
在您的代码中,您
new
在搜索匹配数组时使用关键字,这会创建新的底层数组对象,仅具有相同的元素,但底层是不同的对象。要正确找到具有所需项目的数组的索引,您可以先找到所需的数组(通过使用
FirstOrDefault
和SequenceEqual
- 注意项目必须是按顺序才能工作),然后查找其索引,如下所示:如果您使用 C# 12,则可以使用集合表达式:
IndexOf 方法不能直接作用于数组元素,因为它使用数组的 Equals 方法。该方法检查的是引用相等性,而不是内容相等性。因此,您需要手动比较数组的内容。
因此,我更喜欢使用字符串来表示值,而不是使用 int 数组,这样可以轻松找到值的索引。
另外,您可以尝试实现自己的搜索逻辑,如下所示:
您尝试查找的是
new
数组的索引,而不是列表中的索引。如果您将数组分配给变量,它就会找到它。C# 中的数组相等是指它们是同一个数组,而不是它们具有相同的内容。您需要使用循环或使用 LINQ 方法扫描列表,例如
list.First(x => x.SequenceEqual(needle))
由于您的列表称为坐标,因此我假设列表的所有数组始终都有 2 个元素。由于您的数组不仅仅是一些数字,而且具有实际含义,因此建议创建一个类:
这是一个很大的改进,因为
coordinates[0].X
or会比orcoordinates[0].Y
更能告诉你代码中发生了什么。但是,正如其他答案所指出的那样,你仍然会遇到使用方法找到坐标的问题,因为你的坐标是引用类型。因此,明智的做法是实现并创建自己的比较:coordinates[0][0]
coordinates[0][1]
IndexOf
IEquatable<Coordinate>
如果您重写 Equals,您还必须重写 GetHashCode,即相等的对象也具有相同的哈希码。我刚刚计算了包含 X 和 Y 属性的值元组的哈希码。为了方便起见,我还重载了
==
and!=
运算符。这意味着,您将能够执行类似的事情if(coord1 == coord2) { }
。使用该类,您的代码将变为:在线演示:https://dotnetfiddle.net/ZE7BLr