Как удалить выбранный элемент в массиве?

У меня есть это назначение, где я должен удалить выбранный элемент из массива, поэтому я придумал этот код:

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, либо создавайте новый массив каждый раз, когда вы хотите изменить размер. Если вам не нужно использовать массивы, посмотрите на коллекции, которые вы можете использовать на С#.