Matrices en Visual Basic
Una matriz es un conjunto de valores, denominados elementos, que están relacionados lógicamente entre sí. Por ejemplo, una matriz puede estar compuesta por el número de alumnos de cada curso de una escuela; cada elemento de la matriz es el número de alumnos de un mismo curso. Del mismo modo, una matriz puede representar las calificaciones de un alumno de una clase; cada elemento de la matriz es una única calificación.
Se pueden usar variables individuales para almacenar cada uno de estos elementos de datos. Por ejemplo, si nuestra aplicación analiza las calificaciones de los alumnos, podemos usar una variable independiente para la calificación de cada alumno, como englishGrade1
, englishGrade2
, etc. Este enfoque tiene tres grandes limitaciones:
- Tenemos que saber en tiempo de diseño exactamente cuántas calificaciones tenemos que controlar.
- El control de un gran número de calificaciones puede convertirse rápidamente en una tarea bastante engorrosa. A su vez, esto hace que una aplicación tenga mucho más probabilidades de generar errores graves.
- Es difícil de mantener. Cada nuevo curso que agreguemos requiere modificar, volver a compilar y volver a implementar la aplicación.
Con las matrices se puede hacer referencia a estos valores relacionados usando el mismo nombre, así como utilizar un número denominado índice o subíndice para distinguir un elemento individual en función de su posición dentro de 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 la sintaxis de Visual Basic 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. Podemos trabajar con la matriz como una unidad, mientras que la posibilidad de iterar por sus elementos nos exime 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(,) {{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 una matriz en una matriz sencilla
Vamos a crear una matriz denominada students
donde almacenar el número de estudiantes de cada curso en una escuela. Los índices de los elementos van del 0 al 6. Usar esta matriz es más fácil que declarar siete variables.
En la siguiente ilustración se muestra la matriz students
. 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.
El siguiente ejemplo contiene el código de 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 llevan a cabo tres cosas:
- Se declara una matriz
students
con siete elementos. El número6
en la declaración de matriz indica el último índice de esa matriz (es uno menos que el número total de elementos de la matriz). - Se asignan valores a cada elemento de la matriz. Para acceder a los elementos de matriz, se usa el nombre de la matriz con el índice del elemento individual entre paréntesis.
- Se muestra cada valor de la matriz. En el ejemplo se usa una instrucción
For
para acceder a cada elemento de la matriz por su número de índice.
La matriz students
del ejemplo anterior es una matriz unidimensional, porque usa un índice. Una matriz que use 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 Dimensiones de matriz en Visual Basic.
Creación de una matriz
El tamaño de una matriz se puede definir de varias maneras:
Puede especificar el tamaño al declarar 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
Se puede usar una cláusula
New
para proporcionar el tamaño de la 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 instrucción ReDim
. Puede especificar que la instrucción ReDim
conserve los valores de 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 ReDim (Instrucción).
Almacenamiento de 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 siguiente ejemplo 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
Llenado de una matriz con literales de matriz
Con un literal de matriz, se 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 se determina por el tipo dominante en la lista de valores de literales. El tipo dominante es el tipo al que todos los demás tipos de la matriz se pueden ampliar. 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
, Long
y Double
, la matriz resultante es de tipo Double
. Dado que Integer
y Long
se amplían solo a Double
, Double
es el tipo dominante. Para obtener más información, consulta Widening and Narrowing Conversions.
Nota
La inferencia de tipos solo se puede usar en las matrices que se hayan definido 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 de variable local.
Cabe decir que, en el ejemplo anterior, values
se define como una matriz de tipo Double
, aunque todos los literales de matriz sean de tipo Integer
. Esta matriz se puede crear porque los valores del literal de matriz se pueden ampliar a valores Double
.
También se puede crear y rellenar una matriz multidimensional usando 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 siguiente ejemplo se crea una matriz bidimensional de enteros usando 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 coinciden. También se produce un error si la variable de matriz se declara explícitamente para tener un número diferente de dimensiones que los literales de matriz.
Igual que en las matrices unidimensionales, se puede usar la inferencia de tipos al crear una matriz multidimensional con literales de matriz anidados. El tipo inferido es el tipo dominante de todos los valores de todos los literales de matriz de todos los niveles de anidamiento. En el siguiente ejemplo se crea una matriz bidimensional de tipo Double[,]
a partir de valores del 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.
Recorrido en iteración por una matriz
Cuando una matriz se recorre en iteración, se accede a todos los elementos de la matriz, desde el índice más bajo hasta el más alto. Lo normal es usar la instrucción For...Next o la instrucción For Each...Next para recorrer en iteración los elementos de una matriz. Cuando se desconocen los límites superiores de la matriz, se puede llamar al método Array.GetUpperBound para obtener el valor más alto del índice. Aunque el valor de índice más bajo es casi siempre 0, se puede llamar al método Array.GetLowerBound para obtener dicho valor más bajo.
En el siguiente ejemplo se recorre en iteración una matriz unidimensional usando la instrucción For...Next
.
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
El ejemplo siguiente recorre en iteración una matriz multidimensional mediante el uso de una instrucción For...Next
. 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)
, 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 siguiente ejemplo se usa una instrucción For Each...Next para 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 una 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 siguiente ejemplo se declara una matriz de dos dimensiones con cuatro elementos en cada dimensión. Como se muestra en la salida del ejemplo, el tamaño de la matriz es 16 (o [3+1] x [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 matriz no procede en el caso de las matrices escalonadas. Para obtener información sobre las matrices escalonadas y determinar el tamaño de una matriz de este tipo, vea la sección Matrices escalonadas.
Puede encontrar el tamaño de una matriz mediante la propiedad Array.Length. La longitud de cada dimensión de una matriz multidimensional se puede averiguar utilizando el método Array.GetLength.
El tamaño de una variable de matriz se puede cambiar asignando un nuevo objeto de matriz o usando la instrucción ReDim
. En el ejemplo siguiente se usa la instrucción ReDim
para cambiar una matriz de 100 elementos a una de 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.
Notas | |
---|---|
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 máximo. Por lo tanto, la longitud de una dimensión determinada supera en 1 el límite máximo declarado para 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 datos Integer , 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 se 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 se usan 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 siguiente código declara que la variable arr
es de tipo Array
y llama al método Array.CreateInstance 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 estas razones y para mayor seguridad del tipo, 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 método GetType en la variable para obtener un objeto Type 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 función TypeName para obtener un objeto
String
con el nombre de tipo en tiempo de ejecución.
En el siguiente ejemplo se llama al método GetType
y a la función TypeName
para determinar el tipo de una matriz. El tipo de matriz es Byte(,)
. Cabe mencionar que la propiedad Type.BaseType también indica que el tipo base de la matriz de bytes es la clase Array.
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 siguiente ejemplo, la función GetNumbers
devuelve un objeto Integer()
, una 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 siguiente ejemplo, la función GetNumbersMultiDim
devuelve un objeto 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 máxima de cada día del mes. La primera dimensión de la matriz representa el mes y la segunda dimensión, el número de días, pero el número de días de un mes no es uniforme. Una matriz escalonada, que también se conoce como matriz de matrices, está diseñada para estos casos. 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 siguiente ejemplo se usa una matriz de meses, siendo cada elemento una matriz de días. En el ejemplo se usa una matriz escalonada porque algunos meses tienen números de días distintos. 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 de elemento en elemento usando un bucle For...Next
. También se pueden asignar valores a los elementos de una matriz escalonada usando literales de matriz anidados. Pero si se intenta usar literales de matriz anidados (por ejemplo, Dim valuesjagged = {{1, 2}, {2, 3, 4}}
), se produce el error de compilador BC30568. Para corregirlo, incluya los literales de matriz internos entre paréntesis. Los paréntesis fuerzan la evaluación de la expresión de literal de matriz y los valores resultantes se usan con el literal de matriz exterior, tal y 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 propiedad Array.Length y el método Array.GetLength(0)
devuelven el número de elementos de la matriz unidimensional, y Array.GetLength(1)
produce una excepción IndexOutOfRangeException porque una matriz escalonada es multidimensional. Para determinar el número de elementos de cada submatriz, recupere el valor de la propiedad Array.Length de cada submatriz. 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 diferencia entre una matriz sin inicializar (una matriz cuyo valor es Nothing
) y una matriz de longitud cero o matriz vacía (una matriz que no tiene elementos). Una matriz sin inicializar es aquella que no se ha dimensionado o que no tiene asignados valores. 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:
Aun a riesgo de que se produzca una excepción NullReferenceException, el código debe tener acceso a los miembros de la clase Array, como, por ejemplo, Length o Rank, o bien deben llamar a una función de Visual Basic como UBound.
Conviene que el código usado sea sencillo para no 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.
División de una matriz
En algunos casos, puede que tenga que dividir una matriz en varias. Esto conlleva identificar el punto o los puntos en los que se va a dividir la matriz y, a continuación, dividirla en dos o más matrices independientes.
Nota
En esta sección no se aborda la división de una cadena en una matriz de cadenas usando algún delimitador. Para obtener información sobre cómo dividir una cadena, vea el método String.Split.
Estos son los criterios más comunes para dividir una matriz:
Número de elementos de la matriz. Por ejemplo, lo mejor es dividir una matriz de más de un número de elementos especificado en un número aproximado de partes iguales. Para ello, se puede usar el valor devuelto por los métodos Array.Length o Array.GetLength.
El valor de un elemento, que actúa como delimitador que indica por dónde se debe dividir la matriz. Para hallar un valor específico, llame a los métodos Array.FindIndex y Array.FindLastIndex.
Una vez que haya determinado el índice o los índices en los que se debe dividir la matriz, puede crear las matrices individuales llamando al método Array.Copy.
En el siguiente ejemplo, una matriz se divide en dos matrices de aproximadamente igual tamaño (si el número total de elementos de la 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 siguiente ejemplo, una matriz de cadenas se divide en dos matrices en función de la presencia de un elemento cuyo valor es "zzz", que actúa como delimitador de 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 se puede combinar una serie de matrices en una misma matriz más grande. Para ello, también se usa el método Array.Copy.
Nota
En esta sección no se describe cómo combinar una matriz de cadenas en una misma cadena. Para obtener información sobre cómo combinar una matriz de cadenas, vea el método String.Join.
Antes de copiar los elementos de cada matriz en la nueva matriz, primero debe asegurarse de haber 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 instrucción
ReDim Preserve
para expandir dinámicamente la matriz antes de agregarle nuevos elementos. Esta es la técnica más sencilla, pero puede suponer un empeoramiento del rendimiento y consumir memoria en exceso al copiar matrices grandes. - Calcule el número total de elementos necesarios para la nueva matriz grande y agregue los elementos de cada matriz de origen.
En el siguiente ejemplo se usa el segundo enfoque para agregar cuatro matrices (con diez elementos cada una) a una misma 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.
Dado que en este caso las matrices de origen son todas pequeñas, también podemos expandir dinámicamente la matriz a medida que agregamos 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 cambiar explícitamente el tamaño de una matriz con la instrucción ReDim
, las colecciones crecen y se 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, por lo general 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.
Temas relacionados
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. |