Arrays in Visual Basic
An array is a set of values that are logically related to each other, such as the number of students in each grade in a grammar school.
An array allows you to refer to these related values by the same name and to use a number, called an index or subscript, to tell them apart. The individual values are called the elements of the array. They are contiguous from index 0 through the highest index value.
In contrast to an array, a variable containing a single value is called a scalar variable.
Example
The following example declares an array variable to hold the number of students in each grade in a grammar school.
Dim students(6) As Integer
The array students in the preceding example contains 7 elements. The indexes of the elements range from 0 through 6. Having this array is simpler than declaring 7 different variables.
The following illustration shows the array students. For each element of the array:
The index of the element represents the grade (index 0 represents kindergarten).
The value contained in the element represents the number of students in that grade.
Elements of the "students" array
The following example shows how to refer to the first, second, and last element of the array students.
Dim kindergarten As Integer = students(0)
Dim firstGrade As Integer = students(1)
Dim sixthGrade As Integer = students(6)
MsgBox("Students in kindergarten = " & CStr(kindergarten))
MsgBox("Students in first grade = " & CStr(firstGrade))
MsgBox("Students in sixth grade = " & CStr(sixthGrade))
You can refer to the array as a whole by using just the array variable name without indexes.
Array Dimensions
The array students in the preceding example uses one index and is said to be one-dimensional. An array that uses more than one index or subscript is called multidimensional. For more information, see Array Dimensions in Visual Basic.
Another kind of array is one which holds other arrays as elements. This is known as an array of arrays or a jagged array. A jagged array can be either one-dimensional or multidimensional, and so can its elements. Sometimes the data structure in your application is two-dimensional but not rectangular. For example, you might have an array of months, each element of which is an array of days. Since different months have different numbers of days, the elements do not form a rectangular two-dimensional array. In such a case, you can use a jagged array instead of a multidimensional array.
Declaring an Array
You declare an array variable the same way as any other variable, by using the Dim statement. You follow the variable name with one or more pairs of parentheses to indicate that it is to hold an array rather than a scalar (a variable that contains a single value).
To declare a one-dimensional array variable, add one pair of parentheses after the variable name.
Dim cargoWeights() As Double
To declare a multidimensional array variable, add one pair of parentheses after the variable name and place commas inside the parentheses to separate the dimensions.
Dim atmospherePressures(,,,) As Short
To declare a jagged array variable, add as many pairs of parentheses after the variable name as there are levels of nested arrays.
Dim inquiriesByYearMonthDay()()() As Byte
The preceding examples declare array variables but do not assign arrays to them. You must still create an array, initialize it, and assign it to the variable.
Zero-Length Arrays
An array with no elements is also called a zero-length array. A variable holding a zero-length array does not have the value Nothing. To create an array that has no elements, declare one of the array's dimensions to be -1, as shown in the following example.
Dim twoDimensionalStrings(-1, 3) As String
You might need to create a zero-length array under the following circumstances:
Your code needs to access members of the Array class, such as Length or Rank, or call a Visual Basic function such as UBound, without risking a NullReferenceException exception.
You want to keep the consuming code simpler by not having to check for Nothing as a special case.
Your code interacts with an application programming interface (API) that requires you to pass a zero-length array to one or more procedures, or that returns a zero-length array from one or more procedures.
Creating an Array
An array can be created two ways. You can supply the size of an array when it is declared, or, because an array is an object, so you create it with a New Operator (Visual Basic) clause and assign it to the array variable. You can do this as part of the array declaration, or in a subsequent assignment statement as shown in the following example.
cargoWeights = New Double() {}
atmospherePressures = New Short(,,,) {}
inquiriesByYearMonthDay = New Byte()()() {}
Following the execution of these statements, the arrays are of length 0.
Not
The New clause must specify the type name, followed by parentheses, followed by braces ({}). The parentheses do not represent a call to an array constructor. Instead, they indicate that the object type is an array type. You can supply initialization values inside the braces. The compiler requires the braces even if you are not supplying any values. Therefore, the New clause must include both the parentheses and the braces, even if both contain no values. If you exclude the braces, the complier assumes that you are calling the constructor for the specified type.
You can define the size of an array several different ways. You can supply the size when the array is declared, as shown in the following example.
Dim cargoWeights(10) As Double
Dim atmospherePressures(2, 2, 4, 10) As Short
Dim inquiriesByYearMonthDay(20)()() As Byte
You can also supply the size of an array when it is created by using a New clause, as shown in the following example.
cargoWeights = New Double(10) {}
atmospherePressures = New Short(2, 2, 4, 10) {}
inquiriesByYearMonthDay = New Byte(20)()() {}
If you have an existing array, you can redefine its size by using the Redim statement. You can specify that the Redim statement keep the values that are currently stored in the array, or you can specify that it create a new, empty array. The following example shows different uses of the Redim statement to modify the size of an existing array.
' Assign a new array size and retain the current element values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five element values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)
For more information, see ReDim Statement (Visual Basic).
Populating an Array with Initial Values
You can create an array that contains an initial set of values by using an array literal. An array literal consists of a list of comma-separated values that are enclosed in braces ({}).
When you create an array by using an array literal, you can either supply the array type or use type inference to determine the array type. Both options are shown in the following code.
Dim numbers = New Integer() {1, 2, 4, 8}
Dim doubles = {1.5, 2, 9.9, 18}
When you use type inference, the type of the array is determined by the dominant type in the list of values that is supplied for the array literal. The dominant type is a unique type that all other types in the array literal can widen to. If this unique type cannot be determined, the dominant type is the unique type that all other types in the array can narrow to. If neither of these unique types can be determined, the dominant type is Object. For example, if the list of values supplied to the array literal contains values of type Integer, Long, and Double, the resulting array is of type Double. Both Integer and Long widen to Double and only Double. Therefore, Double is the dominant type. For more information, see Widening and Narrowing Conversions (Visual Basic). These inference rules apply to types inferred for arrays that are local variables defined in a class member. Although you can use array literals when you create class-level variables, you cannot use type inference at the class level. As a result, array literals that are specified at the class level infer the values supplied for the array literal as type Object.
You can explicitly specify the type of the elements in an array that is created by using an array literal. In this case, the values in the array literal must widen to the type of the elements of the array. The following code example creates an array of type Double from a list of integers.
Dim values As Double() = {1, 2, 3, 4, 5, 6}
Nested Array Literals
You can create a multidimensional array by using nested array literals. Nested array literals must have a dimension and number of dimensions, or rank, that is consistent with the resulting array. The following code example creates a two-dimensional array of integers by using an array literal.
Dim grid = {{1, 2}, {3, 4}}
In the previous example, an error would occur if the number of elements in the nested array literals did not match. An error would also occur if the array variable was explicitly declared other than two-dimensional.
Not
You can avoid an error when you supply nested array literals of different dimensions by enclosing the inner array literals in parentheses. The parentheses force the array literal expression to be evaluated, and the resulting values are used with the outer array literal. This is shown in the following code.
Dim values = {({1, 2}), ({3, 4, 5})}
When you create a multidimensional array by using nested array literals, you can use type inference. When you use type inference, the inferred type is the dominant type for all the values in all the array literals for a nesting level. The following code example creates a two-dimensional array of type Double from values that are of type Integer and Double.
Dim a = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}
For additional examples, see How to: Initialize Array Variables in Visual Basic.
Storing Values in an Array
You can access each location in an array by using an index of type Integer. You can store and retrieve values in an array by referencing each array location by using its index enclosed in parentheses. Indexes for multi-dimensional arrays are separated by commas (,).You need one index for each array dimension. The following example shows some statements that store values in arrays.
Dim i = 4
Dim j = 2
Dim numbers(10) As Integer
Dim matrix(5, 5) As Double
numbers(i + 1) = 0
matrix(3, j * 2) = j
The following example shows some statements that get values from arrays.
Dim v = 2
Dim i = 1
Dim j = 1
Dim k = 1
Dim wTotal As Double = 0.0
Dim sortedValues(5), rawValues(5), estimates(2, 2, 2) As Double
Dim lowestValue = sortedValues(0)
wTotal += (rawValues(v) ^ 2)
Dim firstGuess = estimates(i, j, k)
For each array dimension, the GetUpperBound method returns the highest value the index can have. The lowest index value is always 0.
Array Size
The size of an array is the product of the lengths of all its dimensions. It represents the total number of elements currently contained in the array.
The following example declares a three-dimensional array.
Dim prices(3, 4, 5) As Long
The overall size of the array in variable prices is (3 + 1) x (4 + 1) x (5 + 1) = 120.
You can find the size of an array by using the Length property. You can find the length of each dimension of a multi-dimensional array by using the GetLength method.
You can resize an array variable by assigning a new array object to it or by using the ReDim statement.
There are several things to keep in mind when dealing with the size of an array.
Dimension Length |
The index of each dimension is 0-based, which means it ranges from 0 through its upper bound. Therefore, the length of a given dimension is greater by 1 than the declared upper bound for that dimension. |
Length Limits |
The length of every dimension of an array is limited to the maximum value of the Integer data type, which is (2 ^ 31) - 1. However, the total size of an array is also limited by the memory available on your system. If you attempt to initialize an array that exceeds the amount of available RAM, the common language runtime throws an OutOfMemoryException exception. |
Size and Element Size |
An array's size is independent of the data type of its elements. The size always represents the total number of elements, not the number of bytes that they consume in storage. |
Memory Consumption |
It is not safe to make any assumptions regarding how an array is stored in memory. Storage varies on platforms of different data widths, so the same array can consume more memory on a 64-bit system than on a 32-bit system. Depending on system configuration when you initialize an array, the common language runtime (CLR) can assign storage either to pack elements as close together as possible, or to align them all on natural hardware boundaries. Also, an array requires a storage overhead for its control information, and this overhead increases with each added dimension. |
Array Types and Other Types
Data Types
Every array has a data type, but it differs from the data type of its elements. There is no single data type for all arrays. Instead, the data type of an array is determined by the number of dimensions, or rank, of the array, and the data type of the elements in the array. Two array variables are considered to be of the same data type only when they have the same rank and their elements have the same data type. The lengths of the dimensions in an array do not influence the array data type.
Every array inherits from the System.Array class, and you can declare a variable to be of type Array, but you cannot create an array of type Array. Also, the ReDim Statement (Visual Basic) cannot operate on a variable declared as type Array. For these reasons, and for type safety, it is advisable to declare every array as a specific type, such as Integer in the preceding example.
You can find out the data type of either an array or its elements in several ways.
You can call the Object.GetType method on the variable to receive a Type object for the run-time type of the variable. The Type object holds extensive information in its properties and methods.
You can pass the variable to the TypeName function to receive a String containing the name of run-time type.
You can pass the variable to the VarType function to receive a VariantType value representing the type classification of the variable.
The following example calls the TypeName function to determine the type of the array and the type of the elements in the array. The array type is Integer(,) and the elements in the array are of type Integer.
Dim thisTwoDimArray(,) As Integer = New Integer(9, 9) {}
MsgBox("Type of thisTwoDimArray is " & TypeName(thisTwoDimArray))
MsgBox("Type of thisTwoDimArray(0, 0) is " & TypeName(thisTwoDimArray(0, 0)))
Collections as an Alternative to Arrays
Although collections are most often used for working with the Object Data Type, you can use a collection to work with any data type. In some circumstances, it can be more efficient to store items in a collection than in an array.
If you need to change the size of an array, you must use the ReDim Statement (Visual Basic). When you do this, Visual Basic creates a new array and releases the previous array for disposal. This takes execution time. Therefore, if the number of items you are working with changes frequently, or you cannot predict the maximum number of items you need, you might obtain better performance using a collection.
A collection, which does not have to create a new object or copy existing elements, can handle resizing in less execution time than an array, which has to use ReDim. But if the size does not change, or changes only rarely, an array is likely to be more efficient. As always, performance is highly dependent on the individual application. It is often worth your time to try both an array and a collection.
Specialized Collections
The .NET Framework also provides a variety of classes, interfaces, and structures for general and special collections. The System.Collections and System.Collections.Specialized namespaces contain definitions and implementations that include dictionaries, lists, queues, and stacks. The System.Collections.Generic namespace provides many of these in generic versions, which take one or more type arguments.
If your collection is to hold elements of only one specific data type, a generic collection has the advantage of enforcing type safety. For more information on generics, see Generic Types in Visual Basic (Visual Basic).
Specialized Collections
The .NET Framework also provides a variety of classes, interfaces, and structures for general and special collections. The System.Collections and System.Collections.Specialized namespaces contain definitions and implementations that include dictionaries, lists, queues, and stacks. The System.Collections.Generic namespace provides many of these in generic versions, which take one or more type arguments.
If your collection is to hold elements of only one specific data type, a generic collection has the advantage of enforcing type safety. For more information on generics, see Generic Types in Visual Basic (Visual Basic).
Example
The following example uses the .NET Framework generic class System.Collections.Generic.List<T> to create a list collection of Customer objects.
' Define the class for a customer.
Public Class Customer
Public Property Name As String
' Insert code for other members of customer structure.
End Class
' Create a module-level collection that can hold 200 elements.
Public CustomerList As New List(Of Customer)(200)
' Add a specified customer to the collection.
Private Sub AddNewCustomer(ByVal newCust As Customer)
' Insert code to perform validity check on newCust.
CustomerList.Add(newCust)
End Sub
' Display the list of customers in the Debug window.
Private Sub PrintCustomers()
For Each cust As Customer In CustomerList
Debug.WriteLine(cust)
Next cust
End Sub
The declaration of the CustomerFile collection specifies that it can contain elements only of type Customer. It also provides for an initial capacity of 200 elements. The procedure AddNewCustomer checks the new element for validity and then adds it to the collection. The procedure PrintCustomers uses a For Each loop to traverse the collection and display its elements.
Related Topics
Term |
Definition |
---|---|
Explains rank and dimensions in arrays. |
|
Describes how to populate arrays with initial values. |
|
Describes how to reverse the order of the elements of an array. |
|
Shows how to sort the elements of an array alphabetically. |
|
Describes the rules and steps for assigning an array to another array variable. |
|
Discusses what changes are possible and how to accomplish them. |
|
How to: Pass an Array to a Procedure or Property (Visual Basic) |
Explains how to pass an array as an argument to a procedure or property. |
How to: Return an Array from a Procedure or Property (Visual Basic) |
Describes how to return an array to the code that calls a procedure or property. |
Discusses some common problems that arise when working with arrays. |