12

In my Windows Forms application at runtime I will be resizing an array each time I add an element. So first I must resize to the size + 1, and then add a member to this index. How do I do this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alex Gordon
  • 57,446
  • 287
  • 670
  • 1,062

8 Answers8

28

You could use the ReDim statement, but this really isn't your best option. If your array will be changing sizes often, especially as it sounds like you're just appending, you should probably use a generic List(Of T) or similar collection type.

You can use it just like you use an array, with the addition that adding an item to the end is as easy as MyList.Add(item)

To use a generic list, add Imports System.Collections.Generics to the top of the file. Then, you would declare a new integer list like this:

Dim MyList As New List(Of Integer)()

or a string list like this:

Dim MyList As New List(Of String)()

You should get the idea.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
9

Using a generic list is (as suggested) the best idea. If you however want to change the size of an Array, you can use Array.Resize(ByRef arr, newSize).

ReDim is not a good (pretty bad) idea (VB specific legacy, extremely slow).

Corniel Nobel
  • 421
  • 4
  • 12
9

The suggested ReDim's need the Preserve keyword for this scenario.

ReDim Preserve MyArray(n)
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
Jules
  • 4,319
  • 3
  • 44
  • 72
  • 3
    Since this question is over 30,000 views now, I thought it was worth commenting that the "`Preserve`" keyword does **NOT** in fact preserve the original array, but rather allocates a whole new array and copies the elements from the original one by one... which is fine if that's what you want, but usually programmers are expecting something more efficient. – Joel Coehoorn Dec 30 '15 at 16:00
3

I would prefer some type of collection class, but if you WANT to use an array do it like this:

Dim arr() As Integer
Dim cnt As Integer = 0
Dim ix As Integer

For ix = 1 To 1000
    cnt = cnt + 1
    ReDim arr(cnt)
    arr(cnt - 1) = ix
Next
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tekBlues
  • 5,745
  • 1
  • 29
  • 32
  • This becomes N^2. Can you say [Shlemiel the painter's algorithm](http://www.joelonsoftware.com/articles/fog0000000319.html)? – Peter Mortensen Oct 06 '14 at 22:00
  • The argument in the ReDim line is *not* the length, it is the last index. Thus in that line the length of the array becomes cnt+1, leaving an undefined value at the end of the array (well, not actually undefined, but equal to *Nothing*). (It is not very clear from [the documentation](http://msdn.microsoft.com/en-us/library/w8k3cys2.aspx), but perhaps more clear by trying it using Visual Studio's debugger. However, somewhat down in the documentation it says "The upper bound is the highest possible index value for that dimension, not the length of the dimension") – Peter Mortensen Oct 06 '14 at 22:11
2

You can also make your own collection class. A good programming exercise for new programmers.

Public Class MyList
Private Items() As String
Private No As Integer = 0
Public Sub Add(ByVal NewItem As String)

    ''Create a temporary new string array

    Dim CopyString(No) As String

    ''Copy values from Global Variable Items() to new CopyString array

    For i As Integer = 0 To No - 1
        CopyString(i) = Items(i)
    Next

    ''Add new value - NewItem - to CopyString

    CopyString(No) = NewItem

    ''Increment No to No + 1

    No += 1

    ''Copy CopyString to Items

    Items = CopyString

    'Discard CopyString

    CopyString = Nothing

End Sub
Public Sub Show(ByVal index As Integer)
    MsgBox(Items(index))
End Sub
End Class

''Now create a form with a TextBox name - txt, Button1 and Button2

Public Class Form1

''Declare txts as a new MyList Class

Private txts As New MyList

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    ''Add text to txts which is a MyList Class

    txts.Add(txt.Text)
    txt.Text = ""

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    ''Display value at a specific index

    txts.Show(Convert.ToInt16(txt.Text))
    txt.Text = ""

End Sub
End Class
Gaurang
  • 67
  • 8
1

Use the ReDim command to specify the new size.

ReDim MyArray(MyArray.Length + 1)
xeon927
  • 313
  • 2
  • 6
Dillie-O
  • 29,277
  • 14
  • 101
  • 140
  • 1
    this one doesnt work, it gives me Error 1 'ReDim' statements require a parenthesized list of the new bounds of each dimension of the array. – Alex Gordon Jun 08 '09 at 22:59
  • 1
    thanks got it to work this way Redim MyArray, (MyArray.Length + 1) – Alex Gordon Jun 08 '09 at 23:02
  • This increases the array size by 2 rather than 1, due to the fact that `ReDim` expects as its parameter the new _upper bound_, not the length. – Ruud Helderman Dec 30 '15 at 12:47
0

This work for me

    Dim Table1 As New DataTable
    ' Define columns
    Table1.Columns.Add("Column1", GetType(System.String))
    Table1.Columns.Add("Column2", GetType(System.Int32))
    Table1.Columns.Add("Column3", GetType(System.Int32))
    ' Add a row of data
    Table1.Rows.Add("Item1", 44, 99)
    Table1.Rows.Add("Item2", 42, 3)
    Table1.Rows.Add("Item3", 42, 3)
    Table1.Rows.Add("Item4", 42, 3)
    Dim arr(-1) As String
    For Each dr As DataRow In Table1.Rows
        ReDim Preserve arr(arr.Length)
        arr(arr.Length - 1) = dr("Column1")
    Next
Juver Paredes
  • 124
  • 1
  • 2
0

As Joel says, use a list.

Dim MyList As New List(Of String)

Don't forget to change Of String to be Of whichever datatype you're using.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
dsas
  • 1,650
  • 18
  • 30