Як видалити елемент із масиву в C #


153

Скажімо, у мене є цей масив,

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

Як я можу видалити елемент за допомогою "name"? , скажемо, номер 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);
}

Що робити, якщо у вашому списку є дублікати значень? Ви хочете просто видалити перший екземпляр або всі екземпляри?
BenAlabaster

так, у мене немає дублюючих значень, будь-яка ідея?
ахмед

ахмед Ви маєте на увазі, ні, ні, чи так, ви робите? (не ображаючи свою англійську мову, просто прошу роз'яснити)
Malfist

@Malfist - вибачте :), я мав на увазі, що мені не байдуже дублюються значення, тому що я впевнений, що в моєму випадку немає жодного з них, ще раз дякую
ахмед

3
Ви не можете видалити елементи з масивів у C #, як видно з цієї прикладної програми . Що ви можете зробити, це створити новий масив, скопіюйте лише деякі елементи оригіналу та віднесіть його до вихідної змінної. Це те, що робиться у всіх відповідях.
Nicola Musatti

Відповіді:


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();

Редагувати: На випадок, якщо ви цього ще не зрозуміли, як зазначав Malfist, вам потрібно орієнтуватися на .NET Framework 3.5 для того, щоб приклади коду LINQ працювали. Якщо ви орієнтуєтесь на 2.0, вам потрібно посилатися на приклади Non-LINQ.



21

Ви також можете перетворити свій масив у список та викликати видалення зі списку. Потім можна конвертувати назад у свій масив.

int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);

11

Код, написаний у запитанні, має помилку в ньому

Ваш архівник містить рядки "1" "3" "4" "9" та "2" (зверніть увагу на пробіли)

Тож IndexOf (4) нічого не знайде, тому що 4 - це int, і навіть "tostring" перетворив би його на "4", а не в "4", і нічого не буде видалено.

Арраліст - це правильний шлях робити те, що ти хочеш.


Список <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);
    }

4
Resize фактично копіює дані в новий масив (якщо тільки новий розмір не є довжиною переданого масиву); він не змінює розмір переданого екземпляра масиву. Ось чому це еталонний параметр. Див. Посилання referenceource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
фог

5

Видалити з масиву сам по собі непросто, оскільки вам доведеться мати справу із зміною розміру. Це одна з великих переваг використання чогось подібного List<int>. Він пропонує Remove/ RemoveAtв 2.0, і багато розширень LINQ для 3.0.

Якщо можете, рефактор використовувати List<>або подібний.


Я думаю, що це найкраще рішення в цьому випадку.
Богдан Дойчін

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);

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()

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();        
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.