Итак, я пытаюсь найти индекс 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, поэтому я предполагаю, что мой синтаксис неверен (или я использую неправильные инструменты, что также возможно). Есть предложения?
Вы пытаетесь найти индекс массива new
, а не того, что в списке. Если вы присвоите свой массив переменной, она ее найдет.
var yourArray = new int[] { 3, 4 };
coordinates.Add(yourArray);
//...
var index = coordinates.IndexOf(yourArray); //1
Наверное, я не понимаю, в чем разница в подходах. Я ожидаю, что в обоих этих примерах будет одна и та же запись. Разве это не одно и то же? Что мне не хватает? ' координаты.Добавить(новый int[] { 3, 4 }); ' ' var yourArray = new int[] { 3, 4 }; координаты.Добавить(вашмассив); На мой взгляд, они выглядят точно так же, но обрабатываются по-разному.
@JB — они ссылаются на разные объекты (массивы являются ссылочными типами). Вы создали new
, который может напоминать оригинал, но не совпадает с ним.
Например, представьте, что вы приготовили сэндвич с PB&J (извините, я голоден), но затем решили приготовить второй, точно так же, из тех же ингредиентов. Теперь у вас есть 2 одинаковых бутерброда. Вот (по сути) то, что здесь происходит.
Хорошо, это имеет смысл. В моей голове у одного есть уникальный ключ, у другого нет, или что-то в этом роде. Как мне решить эту проблему с моим первоначальным намерением, чтобы иметь возможность определить, что это сэндвич с PB&J, а не какой-то конкретный? Думаю, это мой вопрос.
@JB - Если вы можете присвоить объект переменной, это, как правило, более эффективно. Если по какой-то причине вы не можете или вам просто нужно выполнить поиск, вам может понадобиться что-то вроде одного из ответов, в котором используется SequenceEqual
.
Это имеет смысл. Большое спасибо за вашу помощь! Я ценю это!
Массивы в C# равны, если они представляют собой один и тот же массив, а не имеют одинаковое содержимое. Вам нужно будет сканировать список с помощью цикла или с помощью методов LINQ, например list.First(x => x.SequenceEqual(needle))
.
Массивы в C# являются ссылочными типами. Они равны друг другу, если базовый объект один и тот же.
В вашем коде вы используете ключевое слово new
при поиске соответствующего массива, который создает новый базовый объект массива только с теми же элементами, но под ним находится другой объект.
Чтобы правильно найти индекс массива с нужными элементами, вы можете сначала найти нужный массив (используя FirstOrDefault
и SequenceEqual), а затем найти его индекс, как показано ниже:
var matchingArray = coordinates.FirstOrDefault(x => x.SequenceEqual(new int[] { 3, 4 }));
var index = coordinates.IndexOf(matchingArray);
Метод IndexOf не будет работать напрямую с элементами массива, поскольку для массивов он использует метод Equals. Это проверяет равенство ссылок, а не равенство содержимого. Поэтому сравнивать содержимое массивов нужно вручную.
Итак, вместо использования массива int я бы предпочел значения, представленные в виде строк, что позволяет легко найти индекс значения.
using System.Collections.Generic;
var coordinates = new List<string>();
coordinates.Add("1,2");
coordinates.Add("3,4");
coordinates.Add("5,6");
coordinates.Add("7,8");
coordinates.Add("9,10");
coordinates.Add("11,12");
foreach (string item in coordinates)
{
Console.WriteLine(item);
}
var _valueToSearch = "7,8";
var index = coordinates.IndexOf(_valueToSearch);
Console.WriteLine(index);
Кроме того, вы можете попытаться реализовать свою собственную логику поиска примерно так:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var coordinates = new List<int[]>();
coordinates.Add(new int[] { 1, 2 });
coordinates.Add(new int[] { 3, 4 });
coordinates.Add(new int[] { 5, 6 });
coordinates.AddRange(new int[3][] { new int[] { 7, 8 }, new int[] { 9, 10 }, new int[] { 11, 12 } });
foreach (int[] array in coordinates)
{
Console.WriteLine(string.Join(", ", array));
}
var _valueToSearch = new int[] { 3, 4 };
int index = FindIndex(coordinates, _valueToSearch);
Console.WriteLine(index);
}
static int FindIndex(List<int[]> list, int[] valueToSearch)
{
for (int i = 0; i < list.Count; i++)
{
if (AreArraysEqual(list[i], valueToSearch))
{
return i;
}
}
return -1; // Not found
}
static bool AreArraysEqual(int[] array1, int[] array2)
{
if (array1.Length != array2.Length)
{
return false;
}
for (int i = 0; i < array1.Length; i++)
{
if (array1[i] != array2[i])
{
return false;
}
}
return true;
}
}
Ах, кажется, я следую. Так что дело не в том, что это НЕ МОЖЕТ быть сделано, просто подход экспоненциально сложнее, чем просто обработка его как строки. Приятно это знать! Спасибо за совет, он определенно указал мне лучшее направление!
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var coordinates = new List<int[]>();
coordinates.Add(new int[] { 1, 2 });
coordinates.Add(new int[] { 3, 4 });
coordinates.Add(new int[] { 5, 6 });
coordinates.AddRange(new int[3][]
{
new int[] { 7, 8 },
new int[] { 9, 10 },
new int[] { 11, 12 }
});
foreach (int[] array in coordinates)
{
Console.WriteLine(string.Join(", ", array));
}
var searchArray = new int[] { 3, 4 };
var index = coordinates.FindIndex(arr => arr[0] == searchArray[0]
&& arr[1] == searchArray[1]);
Console.WriteLine(index); // This should now return the correct
index.
}
}
Вы пытаетесь найти индекс массива
new
, а не того, что в списке. Если вы присвоите свой массив переменной, она ее найдет.