Как удалить выбранный элемент в массиве?
У меня есть это назначение, где я должен удалить выбранный элемент из массива, поэтому я придумал этот код:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
Проблема в том, что, допустим, у меня есть массив [1,2,3,4,5,]
, и я хочу удалить 1
. Выходной сигнал будет [2,3,4,5,5]
. Это также происходит, когда я выбираю 2
, но это не происходит, когда я выбираю любое другое число.
Что я делаю неправильно?
Ответы
Ответ 1
Я предполагаю, что вы работаете с базовым массивом строк:
var strItems = new string[] { "1", "2", "3", "4", "5" };
В .NET этот массив всегда будет содержать 5 элементов. Чтобы удалить элемент, вам придется скопировать остальные элементы в новый массив и вернуть его. Установка значения в позиции null
не удаляет его из массива.
Теперь с такими вещами, как LINQ, это очень просто (здесь не показано), или вы можете обманывать с помощью коллекции List<>
и делать это:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
Но я не думаю, что собираюсь научить вас чему-либо.
Первый шаг - найти индекс элемента, который вы хотите удалить. Вы можете использовать Array.IndexOf
, чтобы помочь вам. Найдите средний элемент "3":
int removeIndex = Array.IndexOf(strItems, "3");
Если элемент не был найден, он вернет -1, поэтому проверьте это, прежде чем что-либо делать.
if (removeIndex >= 0)
{
// continue...
}
Наконец, вам нужно скопировать элементы (кроме тех, которые мы не хотим индексировать) в новый массив. Итак, в общем, у вас получилось что-то вроде этого (прокомментировано для объяснения):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
И теперь strItems
будет новый массив, за вычетом значения, указанного для удаления.
Ответ 2
Массивы в С# имеют фиксированный размер. После инициализации вы можете изменять только элементы, но вы не можете добавлять или удалять элементы. Если вы хотите удалить элемент из коллекции, у вас есть два варианта:
1.) Создайте новый массив, который имеет все элементы исходного массива минус тот, который вы хотите удалить.
2.) Используйте тип коллекции, который можно изменить и позволяет добавлять или удалять такие элементы, как List<T>
(List<int>
в вашем случае). Это то, что вы сделали бы в "реальном мире", если ваша коллекция не статична.
Ответ 3
В вашей конкретной реализации я думаю, что вы пропустите инструкцию break;
, вы должны выйти из внешнего цикла, когда вы закончите внутренний цикл. Назначение null не является полезным вообще.
Если список - это всего лишь список чисел, почему вы используете строки? используйте целые числа, если это так.
Ваше упражнение, похоже, спросит что-то вроде этого, если вам нужно удалить только один элемент.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
Эта функция вернет значение true, если оно найдет указанный параметр, false, если нет.
Он будет перемещать все элементы, как описано в вашем примере, но, конечно, он не изменит размер массива.
Массивы являются фиксированными.
Вы не можете изменить размер массива, просто язык не позволяет этого.
Массивы, были и будут всегда фиксированным размером!
Чтобы удалить элемент из массива, вы должны сделать что-то следующее:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
Эта функция создаст новый массив, содержащий все элементы, кроме указанного в указанном вами индексе.
Теперь, почему кто-то будет делать что-то подобное вместо использования списка или словаря или просмотра?
Используйте непосредственно список без использования массива.
Ответ 4
Может использовать метод Except для фильтрации данных
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(FilterData)
Результат будет {10, 50}
Ответ 5
-
Массивы фиксированного размера, вы не можете сократить их длину, не создавая новый массив. Все, что вы можете сделать, это сохранить длину допустимых элементов в массиве (т.е. После удаления 1
длина равна 4).
Кроме того, я не уверен, что порядок элементов в вашем массиве важен, но если это не так, вы можете поменять первый и последний элементы, а не перемещать каждый элемент после того, который удалил вперед 1 позицию.
-
Альтернативой использованию массива является использование коллекции, например ArrayList, которая позаботится об изменении размера, удалении и поддерживая подсчет количества предметов в нем, плюс многое другое.
-
Однако, поскольку это домашняя работа, вам, возможно, придется использовать массивы. Либо отслеживайте длину с переменной, в отличие от использования array.length
, либо создавайте новый массив каждый раз, когда вы хотите изменить размер. Если вам не нужно использовать массивы, посмотрите на коллекции, которые вы можете использовать на С#.