Как удалить элемент из массива в C #

153

Допустим, у меня есть этот массив,

int[] numbers = {1, 3, 4, 9, 2};

Как я могу удалить элемент по имени? допустим номер 4?

Даже ArrayListне помогло удалить?

string strNumbers = " 1, 3, 4, 9, 2";
ArrayList numbers = new ArrayList(strNumbers.Split(new char[] { ',' }));
numbers.RemoveAt(numbers.IndexOf(4));
foreach (var n in numbers)
{
    Response.Write(n);
}
Ahmed
источник
Что если в вашем списке есть повторяющиеся значения? Вы хотите просто удалить первый экземпляр или все экземпляры?
BenAlabaster
да, у меня нет повторяющихся значений, есть идеи?
Ахмед
Ахмед, ты имеешь в виду, нет, нет, или да, вы делаете? (не оскорбляя свой английский, просто прося разъяснений)
Malfist
@Malfist - извините :), я имел в виду, что мне нет дела до дублированных значений, потому что я уверен, что в моем случае их нет, спасибо еще раз
Ахмед
3
Вы не можете удалять элементы из массивов в C #, как вы можете видеть из этого примера программы . Что вы можете сделать, это создать новый массив, скопировать только некоторые элементы исходного и присвоить его исходной переменной. Это то, что сделано во всех ответах.
Никола Мусатти

Ответы:

340

Если вы хотите удалить все экземпляры 4 без необходимости знать индекс:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2 };
int numToRemove = 4;
numbers = numbers.Where(val => val != numToRemove).ToArray();

Non-LINQ: (.NET Framework 2.0)

static bool isNotFour(int n)
{
    return n != 4;
}

int[] numbers = { 1, 3, 4, 9, 2 };
numbers = Array.FindAll(numbers, isNotFour).ToArray();

Если вы хотите удалить только первый экземпляр:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIndex = Array.IndexOf(numbers, numToRemove);
numbers = numbers.Where((val, idx) => idx != numIndex).ToArray();

Non-LINQ: (.NET Framework 2.0)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIdx = Array.IndexOf(numbers, numToRemove);
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(numIdx);
numbers = tmp.ToArray();

Редактировать: на тот случай, если вы еще не поняли, как указал Малфист, вам нужно ориентироваться на .NET Framework 3.5, чтобы примеры кода LINQ работали. Если вы нацелены на 2.0, вам нужно сослаться на примеры, не относящиеся к LINQ.

BenAlabaster
источник
32
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = numbers.Except(new int[]{4}).ToArray();
meetjaydeep
источник
21

Вы также можете преобразовать свой массив в список и вызвать удаление из списка. Затем вы можете преобразовать обратно в ваш массив.

int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);
Дэйв Д.П.
источник
11

Код, который написан в вопросе, содержит ошибку

Ваш arraylist содержит строки «1», «3», «4», «9» и «2» (обратите внимание на пробелы)

Поэтому IndexOf (4) ничего не найдет, потому что 4 - это целое число, и даже «tostring» преобразует его в «4», а не «4», и ничего не будет удалено.

Arraylist - правильный путь, чтобы делать то, что вы хотите.

DevinB
источник
Список <T> будет лучше, чем ArrayList.
Майк Скотт
1
Этот ответ заслуживает большего количества голосов. Хотя я абсолютно согласен с @MikeScott, это List<T>было бы лучше, чем ArrayList, но, похоже, это единственный ответ, который правильно определяет проблему, которая возникла у ОП, когда он пытался использовать ArrayList для решения своей первоначальной проблемы. ОП понимал, что вы не можете изменить размеры массивов, о которых никто другой, похоже, не заметил, и попытался использовать тип с изменяемыми размерами, который никто, кажется, не заметил, а затем столкнулся с другой проблемой, которая больше никому не кажется. чтобы заметили.
Фог
5

Ответ Балабастера правильный, если вы хотите удалить все экземпляры элемента. Если вы хотите удалить только первый, вы должны сделать что-то вроде этого:

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int firstFoundIndex = Array.IndexOf(numbers, numToRemove);
if (numbers >= 0)
{
    numbers = numbers.Take(firstFoundIndex).Concat(numbers.Skip(firstFoundIndex + 1)).ToArray();
}
Воислав Стойкович
источник
5

Я разместил свое решение здесь .

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

    public static void RemoveAt<T>(ref T[] arr, int index)
    {
        for (int a = index; a < arr.Length - 1; a++)
        {
            // moving elements downwards, to fill the gap at [index]
            arr[a] = arr[a + 1];
        }
        // finally, let's decrement Array's size by one
        Array.Resize(ref arr, arr.Length - 1);
    }
infografnet
источник
4
Resize фактически копирует данные в новый массив (если переданный новый размер не равен длине переданного массива); это не меняет размер переданного экземпляра массива. Вот почему это ссылочный параметр. См. Referenceource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
фото
5

Удалить из самого массива не просто, так как вам придется иметь дело с изменением размера. Это одно из больших преимуществ использования чего-то похожего на List<int>. Он предоставляет Remove/ RemoveAtв 2.0 и множество расширений LINQ для 3.0.

Если вы можете, рефакторинг для использования List<>или аналогичные.

ctacke
источник
Я думаю, что это лучшее решение в этом случае.
Богдан Дойцин
3

Как общее расширение, 2.0-совместимый:

using System.Collections.Generic;
public static class Extensions {
    //=========================================================================
    // Removes all instances of [itemToRemove] from array [original]
    // Returns the new array, without modifying [original] directly
    // .Net2.0-compatible
    public static T[] RemoveFromArray<T> (this T[] original, T itemToRemove) {  
        int numIdx = System.Array.IndexOf(original, itemToRemove);
        if (numIdx == -1) return original;
        List<T> tmp = new List<T>(original);
        tmp.RemoveAt(numIdx);
        return tmp.ToArray();
    }
}

Использование:

int[] numbers = {1, 3, 4, 9, 2};
numbers = numbers.RemoveFromArray(4);
Petrucio
источник
0

« Удалить элементы из строки на основе значений словаря. Код VB.net

 Dim stringArr As String() = "file1,file2,file3,file4,file5,file6".Split(","c)
 Dim test As Dictionary(Of String, String) = New Dictionary(Of String, String)
 test.Add("file3", "description")
 test.Add("file5", "description")
 stringArr = stringArr.Except(test.Keys).ToArray()
SP007
источник
0

Вы можете сделать так:

int[] numbers= {1,3,4,9,2};     
List<int> lst_numbers = new List<int>(numbers);
int required_number = 4;
int i = 0;
foreach (int number in lst_numbers)
{              
    if(number == required_number)
    {
        break;
    }
    i++;
}
lst_numbers.RemoveAt(i);
numbers = lst_numbers.ToArray();        

источник