Matrices en Visual Basic

Una matriz es un conjunto de valores, que son elementos denominados, que están relacionados lógicamente entre sí. Por ejemplo, una matriz puede consistir en el número de alumnos de cada grado en una escuela gramatical; cada elemento de la matriz es el número de alumnos en un solo grado. Del mismo modo, una matriz puede constar de las calificaciones de un estudiante para una clase. cada elemento de la matriz es un solo grado.

Es posible que las variables individuales almacenen cada uno de los elementos de datos. Por ejemplo, si nuestra aplicación analiza las calificaciones de los estudiantes, podemos usar una variable independiente para la calificación de cada estudiante, como englishGrade1 , englishGrade2 , etc. Este enfoque tiene tres limitaciones principales:

  • Tenemos que saber en tiempo de diseño exactamente cuántos grados es necesario controlar.
  • Administrar rápidamente un gran número de calificaciones se vuelve difícil. Esto, a su vez, hace que una aplicación tenga mucho más probabilidades de tener errores graves.
  • Es difícil de mantener. Cada nuevo grado que agregues requiere que la aplicación se modifique, se vuelva a compilar y se vuelva a implementar.

Mediante el uso de una matriz, puede hacer referencia a estos valores relacionados con el mismo nombre y usar un número denominado Índice o subíndice para identificar un elemento individual en función de su posición en la matriz. Los índices de una matriz van de 0 a uno menos que el número total de elementos de la matriz. Cuando se usa Visual Basic sintaxis para definir el tamaño de una matriz, se especifica su índice más alto, no el número total de elementos de la matriz. Puede trabajar con la matriz como una unidad y la capacidad de recorrer en iteración sus elementos le libera de tener que saber exactamente cuántos elementos contiene en tiempo de diseño.

Veamos algunos ejemplos rápidos antes de la explicación:

' Declare a single-dimension array of 5 numbers.
Dim numbers(4) As Integer

' Declare a single-dimension array and set its 4 values.
Dim numbers = New Integer() {1, 2, 4, 8}

' Change the size of an existing array to 16 elements and retain the current values.
ReDim Preserve numbers(15)

' Redefine the size of an existing array and reset the values.
ReDim numbers(15)

' Declare a 6 x 6 multidimensional array.
Dim matrix(5, 5) As Double

' Declare a 4 x 3 multidimensional array and set array element values.
Dim matrix = New Integer(3, 2) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}

' Declare a jagged array
Dim sales()() As Double = New Double(11)() {}

Elementos de matriz en una matriz simple

Vamos a crear una matriz denominada students para almacenar el número de alumnos en cada grado en una escuela gramatical. Los índices de los elementos van del 0 al 6. Usar esta matriz es más sencillo que declarar siete variables.

En la ilustración siguiente se muestra la students matriz. Para cada elemento de la matriz:

  • El índice del elemento representa el curso (el índice 0 representa la guardería).

  • El valor que se encuentra en el elemento representa el número de estudiantes en dicho curso.

Diagrama que muestra una matriz de los números de estudiantes

El ejemplo siguiente contiene el código Visual Basic que crea y usa la matriz:


Module SimpleArray
   Public Sub Main()
      ' Declare an array with 7 elements.
      Dim students(6) As Integer

      ' Assign values to each element.
      students(0) = 23
      students(1) = 19
      students(2) = 21
      students(3) = 17
      students(4) = 19
      students(5) = 20
      students(6) = 22
      
      ' Display the value of each element.
      For ctr As Integer = 0 To 6
         Dim grade As String = If(ctr = 0, "kindergarten", $"grade {ctr}")
         Console.WriteLine($"Students in {grade}: {students(ctr)}")
      Next
   End Sub
End Module
' The example displays the following output:
'     Students in kindergarten: 23
'     Students in grade 1: 19
'     Students in grade 2: 21
'     Students in grade 3: 17
'     Students in grade 4: 19
'     Students in grade 5: 20
'     Students in grade 6: 22

En el ejemplo se hace tres cosas:

  • Declara una students matriz con siete elementos. El número 6 de la declaración de matriz indica el último índice de la matriz; es uno menos que el número de elementos de la matriz.
  • Asigna valores a cada elemento de la matriz. Se obtiene acceso a los elementos de matriz utilizando el nombre de la matriz y se incluye el índice del elemento individual entre paréntesis.
  • Muestra cada valor de la matriz. En el ejemplo se usa una For instrucción para tener acceso a cada elemento de la matriz por su número de índice.

La students matriz del ejemplo anterior es una matriz unidimensional porque utiliza un índice. Una matriz que usa más de un índice o subíndice se denomina multidimensional. Para obtener más información, vea el resto de este artículo y las dimensiones de la matriz en Visual Basic.

Crear una matriz

Puede definir el tamaño de una matriz de varias maneras:

  • Puede especificar el tamaño cuando se declara la matriz:

    ' Declare an array with 10 elements.
    Dim cargoWeights(9) As Double               
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(23, 1) As Integer
    ' Declare a jagged array with 31 elements.
    Dim januaryInquiries(30)() As String
    
  • Puede usar una New cláusula para proporcionar el tamaño de una matriz cuando se crea:

    ' Declare an array with 10 elements.
    Dim cargoWeights() As Double = New Double(9) {}
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(,) As Integer = New Integer(23, 1) {}
    ' Declare a jagged array with 31 elements. 
    Dim januaryInquiries()() As String = New String(30)() {}
    

Si tiene una matriz existente, puede volver a definir su tamaño mediante la ReDim instrucción. Puede especificar que la ReDim instrucción Mantenga los valores que se encuentran en la matriz o puede especificar que cree una matriz vacía. El ejemplo siguiente muestra los diferentes usos de la instrucción ReDim para modificar el tamaño de una matriz existente.

' Assign a new array size and retain the current values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)

Para obtener más información, vea la instrucción ReDim.

Almacenar valores en una matriz

Puede tener acceso a cada ubicación en una matriz mediante un índice del tipo Integer. Puede almacenar y recuperar los valores en una matriz haciendo referencia a cada ubicación de la matriz usando su índice entre paréntesis. Los índices de matrices multidimensionales se separan mediante comas (,). Necesita un índice para cada dimensión de la matriz.

En el ejemplo siguiente se muestran algunas instrucciones que almacenan y recuperan valores en las matrices.


Module Example
   Public Sub Main()
      ' Create a 10-element integer array.
      Dim numbers(9) As Integer
      Dim value As Integer = 2
        
      ' Write values to it.
      For ctr As Integer = 0 To 9
         numbers(ctr) = value
         value *= 2
      Next
        
      ' Read and sum the array values.  
      Dim sum As Integer
      For ctr As Integer = 0 To 9
         sum += numbers(ctr)
      Next
      Console.WriteLine($"The sum of the values is {sum:N0}")
    End Sub
End Module
' The example displays the following output:
'     The sum of the values is 2,046

Rellenar una matriz con literales de matriz

Mediante el uso de un literal de matriz, puede rellenar una matriz con un conjunto inicial de valores al mismo tiempo que se crea. Un literal de matriz consta de una lista de valores separados por comas entre llaves ({}).

Cuando se crea una matriz mediante un literal de matriz, puede proporcionar el tipo de matriz o usar la inferencia de tipo para determinar el tipo de matriz. En el ejemplo siguiente se muestran ambas opciones.

' Array literals with explicit type definition.
Dim numbers = New Integer() {1, 2, 4, 8}
' Array literals with type inference.
Dim doubles = {1.5, 2, 9.9, 18}
' Array literals with explicit type definition.
Dim articles() As String = { "the", "a", "an" }

' Array literals with explicit widening type definition.
Dim values() As Double = { 1, 2, 3, 4, 5 }

Cuando se usa la inferencia de tipos, el tipo de la matriz viene determinado por el tipo dominante en la lista de valores literales. El tipo dominante es el tipo al que se pueden ampliar todos los demás tipos de la matriz. Si no se puede determinar este tipo único, el tipo dominante es el tipo único al que todos los demás tipos de la matriz se pueden restringir. Si no se puede determinar ninguno de estos tipos únicos, el tipo dominante es Object. Por ejemplo, si la lista de valores que se proporciona al literal de matriz contiene valores de tipo Integer, Longy Double, la matriz resultante es de tipo Double. Dado Integer Long que y se amplían solo a Double , Double es el tipo dominante. Para obtener más información, consulta Widening and Narrowing Conversions.

Nota

Solo se puede usar la inferencia de tipos para las matrices definidas como variables locales en un miembro de tipo. Si falta una definición de tipo explícita, las matrices definidas con literales de matriz en el nivel de clase son de tipo Object[] . Para obtener más información, vea inferencia de tipo local.

Tenga en cuenta que en el ejemplo anterior values se define como una matriz de tipo, Double aunque todos los literales de matriz son del tipo Integer . Puede crear esta matriz porque los valores del literal de matriz pueden ampliarse a Double valores.

También puede crear y rellenar una matriz multidimensional utilizando literales de matriz anidados. Los literales de matriz anidados deben tener un número de dimensiones que sea coherente con la matriz resultante. En el ejemplo siguiente se crea una matriz bidimensional de enteros utilizando literales de matriz anidados.

' Create and populate a 2 x 2 array.
Dim grid1 = {{1, 2}, {3, 4}}
' Create and populate a 2 x 2 array with 3 elements.
Dim grid2(,) = {{1, 2}, {3, 4}, {5, 6}}

Cuando se usan literales de matriz anidados para crear y rellenar una matriz, se produce un error si el número de elementos de los literales de matriz anidados no coincide. También se produce un error si declara explícitamente que la variable de matriz tiene un número diferente de dimensiones que los literales de matriz.

Al igual que en el caso de las matrices unidimensionales, puede confiar en la inferencia de tipos al crear una matriz multidimensional con literales de matriz anidados. El tipo deducido es el tipo dominante para todos los valores de todos los literales de matriz para todos los niveles de anidamiento. En el ejemplo siguiente se crea una matriz bidimensional de tipo Double[,] a partir de valores que son de tipo Integer y Double .

Dim arr = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}

Para consultar ejemplos adicionales, vea Cómo: Inicializar una variable de matriz en Visual Basic.

Recorrer en iteración una matriz

Cuando recorre en iteración una matriz, tiene acceso a cada elemento de la matriz desde el índice más bajo hasta el más alto o de mayor a menor. Normalmente, use la ... Instrucción siguiente o ... Instrucción siguiente para recorrer en iteración los elementos de una matriz. Si no conoce los límites superiores de la matriz, puede llamar al Array.GetUpperBound método para obtener el valor más alto del índice. Aunque el valor de índice más bajo es casi siempre 0, puede llamar al Array.GetLowerBound método para obtener el valor más bajo del índice.

En el ejemplo siguiente se recorre en iteración una matriz unidimensional mediante la For...Next instrucción.


Module IterateArray
   Public Sub Main()
      Dim numbers = {10, 20, 30}

      For index = 0 To numbers.GetUpperBound(0)
         Console.WriteLine(numbers(index))
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30

En el ejemplo siguiente se recorre en iteración una matriz multidimensional mediante una For...Next instrucción. El método GetUpperBound tiene un parámetro que especifica la dimensión. GetUpperBound(0) Devuelve el índice más alto de la primera dimensión y GetUpperBound(1) devuelve el índice más alto de la segunda dimensión.


Module IterateArray
   Public Sub Main()
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For index0 = 0 To numbers.GetUpperBound(0)
         For index1 = 0 To numbers.GetUpperBound(1)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
' Output 
'  1 2 
'  3 4 
'  5 6

En el ejemplo siguiente se utiliza una para cada... Instrucción siguientepara recorrer en iteración una matriz unidimensional y una matriz bidimensional.


Module IterateWithForEach
   Public Sub Main()
      ' Declare and iterate through a one-dimensional array.
      Dim numbers1 = {10, 20, 30}
      
      For Each number In numbers1
         Console.WriteLine(number)
      Next
      Console.WriteLine()
      
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For Each number In numbers
         Console.WriteLine(number)
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30
'
'  1
'  2
'  3
'  4
'  5
'  6

Tamaño de la matriz

El tamaño de una matriz es el producto de las longitudes de todas sus dimensiones. Representa el número total de elementos contenidos actualmente en la matriz. Por ejemplo, en el ejemplo siguiente se declara una matriz bidimensional con cuatro elementos en cada dimensión. Como muestra la salida del ejemplo, el tamaño de la matriz es 16 (o (3 + 1) * (3 + 1).


Module Example
   Public Sub Main()
      Dim arr(3, 3) As Integer
      Console.WriteLine(arr.Length)     
   End Sub
End Module
' The example displays the following output:
'     16

Nota

Esta explicación del tamaño de la matriz no se aplica a las matrices escalonadas. Para obtener información sobre las matrices escalonadas y determinar el tamaño de una matriz escalonada, consulte la sección matrices escalonadas .

Puede encontrar el tamaño de una matriz mediante la propiedad Array.Length. Puede buscar la longitud de cada dimensión de una matriz multidimensional utilizando el Array.GetLength método.

Puede cambiar el tamaño de una variable de matriz asignando un nuevo objeto de matriz o usando la instrucción de ReDim instrucción . En el ejemplo siguiente se usa la ReDim instrucción para cambiar una matriz de 100 elementos a una matriz de elementos 51.


Module Example
   Public Sub Main()
      Dim arr(99) As Integer
      Console.WriteLine(arr.Length)
      
      Redim arr(50)
      Console.WriteLine(arr.Length)
   End Sub
End Module
' The example displays the following output:
'     100
'     51

 

Hay varios aspectos que se deben tener en cuenta cuando se trabaja con el tamaño de una matriz.

Longitud de la dimensión El índice de cada dimensión es de base 0, lo que significa que va desde 0 hasta su límite superior. Por lo tanto, la longitud de una dimensión determinada es uno mayor que el límite superior declarado de esa dimensión.
Límites de longitud La longitud de cada dimensión de una matriz se limita al valor máximo del tipo de Integer datos, que es Int32.MaxValue o (2 ^ 31)-1. Sin embargo, el tamaño total de una matriz también está limitado por la memoria disponible en el sistema. Si intenta inicializar una matriz que supera la cantidad de memoria disponible, el tiempo de ejecución produce una excepción OutOfMemoryException .
Tamaño y tamaño de elemento El tamaño de la matriz es independiente del tipo de datos de sus elementos. El tamaño siempre representa el número total de elementos, no el número de bytes que consumen en la memoria.
Consumo de memoria No es seguro dar nada por supuesto en lo que respecta al modo de almacenar una matriz en la memoria. El almacenamiento varía en función de las plataformas de diferentes anchos de datos, por lo que la misma matriz puede utilizar más memoria en un sistema de 64 bits que en un sistema de 32 bits. Según la configuración del sistema cuando inicializa una matriz, Common Language Runtime (CLR) puede asignar el almacenamiento para empaquetar los elementos tan juntos como sea posible o para alinearlos todos en los límites naturales del hardware. Asimismo, una matriz requiere una sobrecarga de almacenamiento para obtener su información de control y esta sobrecarga aumenta con cada dimensión agregada.

El tipo de matriz

Cada matriz tiene un tipo de datos, que difiere del tipo de datos de sus elementos. No existe ningún tipo de datos para todas las matrices. En su lugar, el tipo de datos de una matriz lo determina el número de dimensiones, o rango, de la matriz y el tipo de datos de los elementos de la matriz. Dos variables de matriz son del mismo tipo de datos solo cuando tienen el mismo rango y sus elementos tienen el mismo tipo de datos. Las longitudes de las dimensiones de una matriz no influyen en el tipo de datos de la matriz.

Cada matriz hereda la clase System.Array y puede declarar una variable del tipo Array, pero no puede crear una matriz del tipo Array. Por ejemplo, aunque el código siguiente declara la arr variable para que sea de tipo Array y llama al Array.CreateInstance método para crear una instancia de la matriz, el tipo de la matriz demuestra ser Object [].


Module Example
   Public Sub Main()
      Dim arr As Array = Array.CreateInstance(GetType(Object), 19)
      Console.WriteLine(arr.Length)
      Console.WriteLine(arr.GetType().Name)
   End Sub
End Module
' The example displays the following output:
'     19
'     Object[]

Además, la Instrucción ReDim no puede funcionar en una variable declarada de tipo Array. Por estos motivos, y para la seguridad de tipos, es aconsejable declarar cada matriz como un tipo específico.

Puede averiguar el tipo de datos de una matriz o de sus elementos de varias maneras.

  • Puede llamar al GetType método en la variable para obtener un Type objeto que represente el tipo en tiempo de ejecución de la variable. El objeto Type contiene amplia información en sus propiedades y métodos.
  • Puede pasar la variable a la TypeName función para obtener un String con el nombre de tipo en tiempo de ejecución.

En el ejemplo siguiente se llama al GetType método y TypeName a la función para determinar el tipo de una matriz. El tipo de matriz es Byte(,) . Tenga en cuenta que la Type.BaseType propiedad también indica que el tipo base de la matriz de bytes es la Array clase.


Module Example
   Public Sub Main()
      Dim bytes(9,9) As Byte
      Console.WriteLine($"Type of {nameof(bytes)} array: {bytes.GetType().Name}")
      Console.WriteLine($"Base class of {nameof(bytes)}: {bytes.GetType().BaseType.Name}")
      Console.WriteLine()
      Console.WriteLine($"Type of {nameof(bytes)} array: {TypeName(bytes)}")
   End Sub
End Module
' The example displays the following output:
' Type of bytes array: Byte[,]
' Base class of bytes: Array
' 
' Type of bytes array: Byte(,)


Matrices como valores devueltos y parámetros

Para devolver una matriz desde un procedimiento Function, especifique el tipo de datos de matriz y el número de dimensiones como tipo de valor devuelto de la Instrucción Function. Dentro de la función, declare una variable de matriz local con el mismo tipo de datos y número de dimensiones. En la Instrucción Return, incluya la variable de matriz local sin paréntesis.

Para especificar una matriz como parámetro para un procedimiento Sub o Function , defina el parámetro como una matriz con un tipo de datos especificado y el número de dimensiones. En la llamada al procedimiento, pase una variable de matriz con el mismo tipo de datos y número de dimensiones.

En el ejemplo siguiente, la GetNumbers función devuelve una Integer() matriz unidimensional de tipo Integer . El procedimiento ShowNumbers acepta un argumento Integer() .


Module ReturnValuesAndParams
   Public Sub Main()
      Dim numbers As Integer() = GetNumbers()
      ShowNumbers(numbers)
   End Sub

   Private Function GetNumbers() As Integer()
      Dim numbers As Integer() = {10, 20, 30}
      Return numbers
   End Function

   Private Sub ShowNumbers(numbers As Integer())
      For index = 0 To numbers.GetUpperBound(0)
         Console.WriteLine($"{numbers(index)} ")
      Next
   End Sub
End Module
' The example displays the following output:
'   10
'   20
'   30
    

En el ejemplo siguiente, la GetNumbersMultiDim función devuelve un Integer(,) , una matriz bidimensional de tipo Integer . El procedimiento ShowNumbersMultiDim acepta un argumento Integer(,) .


Module Example
   Public Sub Main()
      Dim numbers As Integer(,) = GetNumbersMultidim()
      ShowNumbersMultidim(numbers)
   End Sub

   Private Function GetNumbersMultidim() As Integer(,)
      Dim numbers As Integer(,) = {{1, 2}, {3, 4}, {5, 6}}
      Return numbers
   End Function

   Private Sub ShowNumbersMultidim(numbers As Integer(,))
      For index0 = 0 To numbers.GetUpperBound(0)
         For index1 = 0 To numbers.GetUpperBound(1)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'     1 2
'     3 4
'     5 6

Matrices escalonadas

A veces la estructura de datos de la aplicación es bidimensional pero no rectangular. Por ejemplo, puede usar una matriz para almacenar datos sobre la temperatura alta de cada día del mes. La primera dimensión de la matriz representa el mes, pero la segunda dimensión representa el número de días, y el número de días de un mes no es uniforme. Una matriz escalonada, que también se denomina matriz de matrices, está diseñada para estos escenarios. Una matriz escalonada es una matriz cuyos elementos también son matrices. Una matriz escalonada y cada elemento de una matriz escalonada pueden tener una o más dimensiones.

En el ejemplo siguiente se utiliza una matriz de meses, donde cada elemento es una matriz de días. En el ejemplo se usa una matriz escalonada porque los distintos meses tienen un número diferente de días. En el ejemplo se muestra cómo crear una matriz escalonada, asignarle valores y recuperar y mostrar sus valores.

Imports System.Globalization

Module JaggedArray
   Public Sub Main()
      ' Declare the jagged array of 12 elements. Each element is an array of Double.
      Dim sales(11)() As Double
      ' Set each element of the sales array to a Double array of the appropriate size.
      For month As Integer = 0 To 11
         ' The number of days in the month determines the appropriate size.
         Dim daysInMonth As Integer =
            DateTime.DaysInMonth(Year(Now), month + 1)
         sales(month) = New Double(daysInMonth - 1) {}
      Next 

      ' Store values in each element.
      For month As Integer = 0 To 11
         For dayOfMonth = 0 To sales(month).GetUpperBound(0)
            sales(month)(dayOfMonth) = (month * 100) + dayOfMonth
         Next
      Next

      ' Retrieve and display the array values.
      Dim monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
      ' Display the month names.
      Console.Write("    ")
      For ctr = 0 To sales.GetUpperBound(0)
         Console.Write($" {monthNames(ctr)}   ")
      Next   
      Console.WriteLine()
      ' Display data for each day in each month.
      For dayInMonth = 0 To 30
         Console.Write($"{dayInMonth + 1,2}.  ")
         For monthNumber = 0 To sales.GetUpperBound(0)
            If dayInMonth > sales(monthNumber).GetUpperBound(0) Then 
               Console.Write("       ")
            Else
               Console.Write($"{sales(monthNumber)(dayInMonth),-5}  ")
            End If
         Next   
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'      Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct    Nov    Dec
'  1.  0      100    200    300    400    500    600    700    800    900    1000   1100
'  2.  1      101    201    301    401    501    601    701    801    901    1001   1101
'  3.  2      102    202    302    402    502    602    702    802    902    1002   1102
'  4.  3      103    203    303    403    503    603    703    803    903    1003   1103
'  5.  4      104    204    304    404    504    604    704    804    904    1004   1104
'  6.  5      105    205    305    405    505    605    705    805    905    1005   1105
'  7.  6      106    206    306    406    506    606    706    806    906    1006   1106
'  8.  7      107    207    307    407    507    607    707    807    907    1007   1107
'  9.  8      108    208    308    408    508    608    708    808    908    1008   1108
' 10.  9      109    209    309    409    509    609    709    809    909    1009   1109
' 11.  10     110    210    310    410    510    610    710    810    910    1010   1110
' 12.  11     111    211    311    411    511    611    711    811    911    1011   1111
' 13.  12     112    212    312    412    512    612    712    812    912    1012   1112
' 14.  13     113    213    313    413    513    613    713    813    913    1013   1113
' 15.  14     114    214    314    414    514    614    714    814    914    1014   1114
' 16.  15     115    215    315    415    515    615    715    815    915    1015   1115
' 17.  16     116    216    316    416    516    616    716    816    916    1016   1116
' 18.  17     117    217    317    417    517    617    717    817    917    1017   1117
' 19.  18     118    218    318    418    518    618    718    818    918    1018   1118
' 20.  19     119    219    319    419    519    619    719    819    919    1019   1119
' 21.  20     120    220    320    420    520    620    720    820    920    1020   1120
' 22.  21     121    221    321    421    521    621    721    821    921    1021   1121
' 23.  22     122    222    322    422    522    622    722    822    922    1022   1122
' 24.  23     123    223    323    423    523    623    723    823    923    1023   1123
' 25.  24     124    224    324    424    524    624    724    824    924    1024   1124
' 26.  25     125    225    325    425    525    625    725    825    925    1025   1125
' 27.  26     126    226    326    426    526    626    726    826    926    1026   1126
' 28.  27     127    227    327    427    527    627    727    827    927    1027   1127
' 29.  28            228    328    428    528    628    728    828    928    1028   1128
' 30.  29            229    329    429    529    629    729    829    929    1029   1129
' 31.  30            230           430           630    730           930           1130

En el ejemplo anterior se asignan valores a la matriz escalonada en función de cada elemento mediante un For...Next bucle. También puede asignar valores a los elementos de una matriz escalonada utilizando literales de matriz anidados. Sin embargo, el intento de usar literales de matriz anidados (por ejemplo, Dim valuesjagged = {{1, 2}, {2, 3, 4}} ) genera el error del compilador BC30568. Para corregir el error, incluya los literales de matriz internos entre paréntesis. Los paréntesis fuerzan la evaluación de la expresión literal de matriz y los valores resultantes se usan con el literal de matriz externo, como se muestra en el ejemplo siguiente.


Module Example
   Public Sub Main()
      Dim values1d = { 1, 2, 3 }
      Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
      Dim valuesjagged = {({1, 2}), ({2, 3, 4})}
   End Sub
End Module

Una matriz escalonada es una matriz unidimensional cuyos elementos contienen matrices. Por lo tanto, la Array.Length propiedad y el Array.GetLength(0) método devuelven el número de elementos de la matriz unidimensional y Array.GetLength(1) produce una excepción IndexOutOfRangeException porque una matriz escalonada no es multidimensional. El número de elementos de cada submatriz se determina mediante la recuperación del valor de cada propiedad de la submatriz Array.Length . En el ejemplo siguiente se muestra cómo determinar el número de elementos de una matriz escalonada.


Module Example
   Public Sub Main()
      Dim jagged = { ({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10}) }
      Console.WriteLine($"The value of jagged.Length: {jagged.Length}.")
      Dim total = jagged.Length
      For ctr As Integer = 0 To jagged.GetUpperBound(0)
         Console.WriteLine($"Element {ctr + 1} has {jagged(ctr).Length} elements.") 
         total += jagged(ctr).Length 
      Next
      Console.WriteLine($"The total number of elements in the jagged array: {total}")
   End Sub
End Module
' The example displays the following output:
'     The value of jagged.Length: 4.
'     Element 1 has 2 elements.
'     Element 2 has 3 elements.
'     Element 3 has 2 elements.
'     Element 4 has 4 elements.
'     The total number of elements in the jagged array: 15

Matrices de longitud cero

Visual Basic distingue entre una matriz no inicializada (una matriz cuyo valor es Nothing ) y una matriz de longitud cero o una matriz vacía (una matriz que no tiene elementos). Una matriz no inicializada es aquella que no se ha acotado o que no tiene asignado ningún valor. Por ejemplo:

Dim arr() As String

Una matriz de longitud cero se declara con una dimensión de-1. Por ejemplo:

Dim arrZ(-1) As String

Puede que tenga que crear una matriz de longitud cero en las circunstancias siguientes:

  • Sin arriesgarse a una NullReferenceException excepción, el código debe tener acceso a los miembros de la Array clase, como Length o Rank , o llamar a una función de Visual Basic como UBound .

  • Desea mantener el código sencillo sin tener que comprobar Nothing como caso especial.

  • El código interactúa con una interfaz de programación de aplicaciones (API) que requiere pasar una matriz de longitud cero a uno o más procedimientos o que devuelve una matriz de longitud cero desde uno o más procedimientos.

Dividir una matriz

En algunos casos, puede que necesite dividir una matriz única en varias matrices. Esto implica identificar el punto o los puntos en los que se va a dividir la matriz y, a continuación, spitting la matriz en dos o más matrices independientes.

Nota

En esta sección no se explica la división de una cadena única en una matriz de cadenas basada en algún delimitador. Para obtener información sobre cómo dividir una cadena, vea el String.Split método.

Los criterios más comunes para dividir una matriz son:

  • Número de elementos de la matriz. Por ejemplo, puede dividir una matriz de más de un número especificado de elementos en un número de partes aproximadamente iguales. Para este propósito, puede utilizar el valor devuelto por el Array.Length método o Array.GetLength .

  • El valor de un elemento, que actúa como delimitador que indica dónde se debe dividir la matriz. Para buscar un valor específico, puede llamar a los Array.FindIndex Array.FindLastIndex métodos y.

Una vez que haya determinado los índices en los que se debe dividir la matriz, puede crear las matrices individuales llamando al Array.Copy método.

En el ejemplo siguiente se divide una matriz en dos matrices de aproximadamente el mismo tamaño. (Si el número total de elementos de matriz es impar, la primera matriz tiene un elemento más que el segundo).


Module Example
   Public Sub Main()
      ' Create an array of 100 elements.
      Dim arr(99) As Integer
      ' Populate the array.
      Dim rnd As new Random()
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = rnd.Next()
      Next
      
      ' Determine how many elements should be in each array.
      Dim divisor = 2
      Dim remainder As Integer
      Dim boundary = Math.DivRem(arr.GetLength(0), divisor, remainder)
            
      ' Copy the array.
      Dim arr1(boundary - 1 + remainder), arr2(boundary - 1) as Integer
      Array.Copy(arr, 0, arr1, 0, boundary + remainder)
      Array.Copy(arr, boundary + remainder, arr2, 0, arr.Length - boundary) 
   End Sub
End Module

En el ejemplo siguiente se divide una matriz de cadenas en dos matrices en función de la presencia de un elemento cuyo valor es "Zzz", que actúa como delimitador de la matriz. Las nuevas matrices no incluyen el elemento que contiene el delimitador.


Module Example
   Public Sub Main()
      Dim rnd As New Random()
      
      ' Create an array of 100 elements.
      Dim arr(99) As String
      ' Populate each element with an arbitrary ASCII character.
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = ChrW(Rnd.Next(&h21, &h7F))
      Next
      ' Get a random number that will represent the point to insert the delimiter.
      arr(rnd.Next(0, arr.GetUpperBound(0))) = "zzz"

      ' Find the delimiter.
      Dim location = Array.FindIndex(arr, Function(x) x = "zzz")

      ' Create the arrays.
      Dim arr1(location - 1) As String
      Dim arr2(arr.GetUpperBound(0) - location - 1) As String
      
      ' Populate the two arrays.
      Array.Copy(arr, 0, arr1, 0, location)
      Array.Copy(arr, location + 1, arr2, 0, arr.GetUpperBound(0) - location)
   End Sub
End Module

Combinación de matrices

También puede combinar varias matrices en una sola matriz mayor. Para ello, también se usa el Array.Copy método.

Nota

En esta sección no se explica cómo combinar una matriz de cadenas en una sola cadena. Para obtener información sobre cómo combinar una matriz de cadenas, vea el String.Join método.

Antes de copiar los elementos de cada matriz en la nueva matriz, primero debe asegurarse de que ha inicializado la matriz para que sea lo suficientemente grande como para dar cabida a la nueva matriz. Puede hacerlo de una de las maneras siguientes:

  • Use la ReDim Preserve instrucción para expandir dinámicamente la matriz antes de agregarle nuevos elementos. Esta es la técnica más sencilla, pero puede producir una degradación del rendimiento y un consumo excesivo de memoria cuando se copian matrices de gran tamaño.
  • Calcule el número total de elementos necesarios para la nueva matriz grande y, a continuación, agregue los elementos de cada matriz de origen a él.

En el ejemplo siguiente se usa el segundo método para agregar cuatro matrices con diez elementos cada una a una sola matriz.

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())
       ' Compute the number of elements in all arrays.
       Dim elements = 0
       For Each task In tasks
          elements += task.Result.Length
       Next
       Dim newArray(elements - 1) As Integer
       Dim index = 0
       For Each task In tasks
          Dim n = task.Result.Length
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

Puesto que en este caso las matrices de origen son pequeñas, también podemos expandir dinámicamente la matriz a medida que se agregan los elementos de cada nueva matriz a ella. En el siguiente ejemplo se realiza esto.

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())

       ' Dimension the target array and copy each element of each source array to it.
       Dim newArray() As Integer = {}
       ' Define the next position to copy to in newArray.
       Dim index = 0
       For Each task In tasks
          Dim n = Task.Result.Length
          ReDim Preserve newArray(newArray.GetUpperBound(0) + n)
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

Colecciones como alternativa a las matrices

Las matrices son muy útiles para crear y trabajar con un número fijo de objetos fuertemente tipados. Las colecciones proporcionan una manera más flexible de trabajar con grupos de objetos. A diferencia de las matrices, que requieren que se cambie explícitamente el tamaño de una matriz con la ReDim instrucción, las colecciones crecen y reducen dinámicamente a medida que cambian las necesidades de una aplicación.

Cuando se usa ReDim para redimensionar una matriz, Visual Basic crea una nueva matriz y libera la anterior. Esto requiere tiempo de ejecución. Por lo tanto, si el número de elementos con los que trabaja cambia con frecuencia, o si no puede predecir el número máximo de elementos que necesita, normalmente obtendrá un mejor rendimiento si usa una colección.

Para algunas colecciones, puede asignar una clave a cualquier objeto que incluya en la colección para, de este modo, recuperar rápidamente el objeto con la clave.

Si la colección contiene elementos de un solo tipo de datos, puede usar una de las clases del espacio de nombres System.Collections.Generic. Una colección genérica cumple la seguridad de tipos para que ningún otro tipo de datos se pueda agregar a ella.

Para más información sobre las colecciones, vea Colecciones.

Término Definición
Array Dimensions in Visual Basic Explica el rango y las dimensiones de las matrices.
Cómo: Inicializar una variable de matriz en Visual Basic Describe cómo se llenan las matrices con valores iniciales.
Cómo: Ordenar una matriz en Visual Basic Muestra cómo ordenar alfabéticamente los elementos de una matriz.
Procedimiento para asignar una matriz a otra Describe las reglas y los pasos para asignar una matriz a otra variable de matriz.
Solución de problemas de matrices Describe algunos problemas comunes que surgen al trabajar con matrices.

Consulte también