Как я могу удалить элемент из массива в VB.NET?

Как я могу удалить элемент из массива в VB. NET ?

26
задан Peter Mortensen 18 June 2012 в 03:42
поделиться

3 ответа

Вы не можете. Я бы посоветовал вам поместить элементы массива в List , по крайней мере, тогда вы сможете удалять элементы. Массив можно расширить, например, с помощью ReDim , но вы не можете удалить элементы массива после того, как они были созданы. Для этого вам придется перестроить массив с нуля.

Если вы можете этого избежать, не используйте здесь массивы, используйте Список .

11
ответ дан 28 November 2019 в 07:14
поделиться

Как сказал Хейнци, массив имеет фиксированный размер. Чтобы «удалить элемент» или «изменить его размер», вам нужно будет создать новый массив с желаемым размером и скопировать нужные вам элементы по мере необходимости.

Вот код для удаления элемента из массива:

<System.Runtime.CompilerServices.Extension()> _
Function RemoveAt(Of T)(ByVal arr As T(), ByVal index As Integer) As T()
    Dim uBound = arr.GetUpperBound(0)
    Dim lBound = arr.GetLowerBound(0)
    Dim arrLen = uBound - lBound

    If index < lBound OrElse index > uBound Then
        Throw New ArgumentOutOfRangeException( _
        String.Format("Index must be from {0} to {1}.", lBound, uBound))

    Else
        'create an array 1 element less than the input array
        Dim outArr(arrLen - 1) As T
        'copy the first part of the input array
        Array.Copy(arr, 0, outArr, 0, index)
        'then copy the second part of the input array
        Array.Copy(arr, index + 1, outArr, index, uBound - index)

        Return outArr
    End If
End Function

Вы можете использовать его как таковой:

Module Module1

    Sub Main()
        Dim arr = New String() {"abc", "mno", "xyz"}
        arr.RemoveAt(1)
    End Sub
End Module

Приведенный выше код удаляет второй элемент ( «mno» ) [с индексом 1] из массива.

Чтобы использовать метод расширения, вы должны разрабатывать на .NET 3.5 или выше. Если вы используете .NET 2.0 или 3.0, вы можете вызвать метод как таковой

arr = RemoveAt(arr, 1)

. Надеюсь, это то, что вам нужно.

Обновление

После выполнения тестов на основе комментария ToolMakerSteve выяснилось, что исходный код не изменяет массив, который вы хотите обновить, из-за ByVal , используемого в объявлении функции. Однако написание кода типа arr = arr.RemoveAt (1) или arr = RemoveAt (arr, 1) действительно изменяет массив, поскольку он переназначает измененный массив на исходный.

Найдите ниже обновленный метод (подпрограмму) для удаления элемента из массива.

<System.Runtime.CompilerServices.Extension()> _
Public Sub RemoveAt(Of T)(ByRef arr As T(), ByVal index As Integer)
    Dim uBound = arr.GetUpperBound(0)
    Dim lBound = arr.GetLowerBound(0)
    Dim arrLen = uBound - lBound

    If index < lBound OrElse index > uBound Then
        Throw New ArgumentOutOfRangeException( _
        String.Format("Index must be from {0} to {1}.", lBound, uBound))

    Else
        'create an array 1 element less than the input array
        Dim outArr(arrLen - 1) As T
        'copy the first part of the input array
        Array.Copy(arr, 0, outArr, 0, index)
        'then copy the second part of the input array
        Array.Copy(arr, index + 1, outArr, index, uBound - index)

        arr = outArr
    End If
End Sub

Использование метода аналогично оригинальному, за исключением того, что на этот раз нет возвращаемого значения, поэтому попытка присвоить массив из возвращаемого значения не будет работать, потому что ничего не возвращается.

Dim arr = New String() {"abc", "mno", "xyz"}
arr.RemoveAt(1)  ' Output: {"abc", "mno"} (works on .NET 3.5 and higher)
RemoveAt(arr, 1) ' Output: {"abc", "mno"} (works on all versions of .NET fx)
arr = arr.RemoveAt(1)  'will not work; no return value
arr = RemoveAt(arr, 1) 'will not work; no return value

Примечание:

  1. Я использую временный массив для процесса, потому что он проясняет мои намерения, и это именно то, что VB.NET делает за кулисами, когда вы выполняете Redim Preserve . Если вы хотите изменить массив на месте, используя Redim Preserve , см. ответ ToolmakerSteve .
  2. Записанные здесь методы RemoveAt являются методами расширения. Чтобы они работали, вам нужно будет вставить их в Module . Методы расширения не будут работать в VB.NET, если они помещены в класс .

  3. Важно Если вы будете изменять свой массив с большим количеством «удаляемых», настоятельно рекомендуется использовать другую структуру данных, такую ​​как Список (Of T) , как было предложено другими ответчиками на этот вопрос.

13
ответ дан 28 November 2019 в 07:14
поделиться

Это зависит от того, что вы имеете в виду под удалить . Массив имеет фиксированный размер, поэтому удаление не имеет смысла.

Если вы хотите удалить элемент i , можно переместить все элементы j> i на одну позицию влево ( a [j - 1] = a [j] для всех j или с помощью Array.Copy ), а затем измените размер массива с помощью ReDim Preserve .

Итак, если вы не вынуждены использовать массив из-за какого-либо внешнего ограничения, подумайте об использовании структуры данных, более подходящей для добавления и удаления элементов. List , например, также использует массив внутри, но сам заботится обо всех проблемах изменения размера: для удаления элементов он использует алгоритм, упомянутый выше (без ReDim), поэтому List .RemoveAt - это операция O (n) .

В пространстве имен System.Collections.Generic имеется множество различных классов коллекций, оптимизированных для различных случаев использования. Если требуется частое удаление элементов, есть много лучших вариантов, чем массив (или даже List ).

4
ответ дан 28 November 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: