Una matriz es un conjunto de valores, que se denominan elementos, que están relacionados lógicamente entre sí. Un Array o matriz, es un tipo especial de variable que permite almacenar un grupo de datos o valores del mismo tipo. Por ejemplo, una matriz puede constar del número de alumnos de cada grado de una escuela gramatical; cada elemento de la matriz es el número de alumnos de un solo grado.
Es posible usar variables individuales para almacenar cada uno de nuestros 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. El control de un gran número de calificaciones puede convertirse rápidamente en una tarea bastante engorrosa. Es difícil mantenerlo. Por ejemplo, si se desea almacenar el nombre de los once jugadores titulares o principales de un equipo de FootBall, puede crear once variables, una para cada jugador, pero también tiene la opción de crear una Matriz ó Array en donde puede almacenar los once datos de todos los jugadores.
Mediante el uso de una matriz, puede hacer referencia a estos valores relacionados por 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 oscilan entre 0 y uno menor que el número total de elementos de la matriz.
Declaración de Arrays en Visual Basic
En Visual Basic 2010 la declaración de un array, arreglo o vector la hacemos de la misma forma que en Visual Basic 6. La declaración de una matriz se hace usando la palabra Dim como se hace normalmente en la declaración de variable, pero va seguida de un paréntesis. Como podemos apreciar, luego de la cláusula «Dim», especificamos el nombre con el cual se identificará nuestro arreglo, seguido de la dimensión y «As» detallando el tipo de dato que contendrá; luego procedemos a llenar nuestro Array.
Índices basados en cero
Una matriz está formada por una serie de elementos que comienza desde el número cero. 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. Por ejemplo, para declarar una Matriz que contendrá los datos de 11 jugadores de un equipo de fútbol, sería Dim Jugadores (10) As String, porque se cuenta desde 0 hasta 10. Si el total de datos fuese 100, entonces entre paréntesis se escribiría 99; para ser más claro, entre paréntesis se escribe el total de elementos menos 1.
Lea también: IVA 21% Excel
Declaración de tamaño fijo y flexible
Si se conoce el número de datos que se almacenarán, se puede poner este entre los paréntesis. Si se desconoce el número de elementos, entonces el paréntesis queda sin datos, por ejemplo: Dim Jugadores () As String.
Inicialización y Asignación de Valores
Una vez creada la matriz, es necesario asignarle los valores haciendo referencia al número del elemento, como parte de la asignación. Por ejemplo, para asignar valores a la matriz de jugadores de un equipo deportivo, sería así:
- Jugador(0)=”Luis”
- Jugador(1)=”Luisito”
- ...
- Jugador(10)=”Jimmy”
Con un literal de matriz, se puede rellenar una matriz con un conjunto inicial de valores al mismo tiempo que se crea. 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. Otra manera de declarar la lista de valores es escribiéndolos en una sola línea, pero en este caso se utilizan las llaves, como se ve a continuación: Dim Jugadores() As Integer = {1,2,3,4,5,6,7,8,9,10}. Observe que no se escribió el total entre paréntesis porque se escribió cada uno de ellos entre las llaves.
Para inicializar una variable de matriz, incluye un literal de matriz en una New cláusula y especifica los valores iniciales de la matriz. Puedes especificar el tipo o permitir que se infiera a partir de los valores del literal de matriz. En la New cláusula o al asignar el valor de la matriz, proporciona los valores de elemento dentro de llaves ({}). Una vez ejecutada cada instrucción, la matriz creada tiene una longitud de 3, con elementos en el índice 0 al índice 2 que contienen los valores iniciales. Observa que no es necesario especificar el límite superior del índice si proporcionas valores de elemento en un literal de matriz.
Tipos de Arrays
Arrays Unidimensionales
Una matriz unidimensional es una secuencia de elementos similares. Puede acceder a un elemento a través de su índice. El índice es la posición ordinal del elemento en la secuencia. La students matriz del ejemplo anterior es una matriz unidimensional porque usa un índice.
Lea también: Guía IVA reducido
Arrays Multidimensionales
Una matriz que usa más de un índice o subíndice se denomina multidimensional. Los índices de matrices multidimensionales están separados por comas (,). En el caso de querer declarar una matriz (array o arreglo de varias dimensiones) como M (5, 7) que podría representar una tabla con datos como por ejemplo M (0,0) = 33, M (0,1) = 18, M (0,2) = 41… etc.
- En las versiones menos recientes de Visual Basic, declararemos inicialmente Dim M() As Integer y posteriormente ReDim M (5, 7).
- En las versiones más recientes de Visual Basic, declararemos inicialmente Dim M( , ) As Integer, donde la coma indica que van a existir dos dimensiones que se declararán posteriormente. Si fuéramos a declarar posteriormente tres dimensiones escribiríamos Dim M ( , , ) As Integer, para 4 dimensiones Dim M ( , , , ) y así sucesivamente.
También se puede crear y rellenar una matriz multidimensional usando literales de matriz anidados. Los literales de matriz anidados deben tener una serie de dimensiones coherentes con la matriz resultante. 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 anidada no coinciden. Anida valores dentro de llaves ({}) dentro de llaves. Asegúrate de que los literales de matriz anidados inferen como matrices del mismo tipo y longitud.
Puedes especificar explícitamente los límites de la matriz o dejarlos fuera y hacer que el compilador infiera los límites de la matriz en función de los valores del literal de matriz. Si proporciona los límites superiores y los valores, debe incluir un valor para cada elemento del índice 0 hasta el límite superior de cada dimensión. Después de ejecutar cada instrucción, la matriz creada contiene seis elementos inicializados que tienen índices (0,0), (0,1), (0,2), (1,0), (1,1) y (1,2).
Arrays Escalonados (Jagged Arrays)
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. En el ejemplo siguiente se usa una matriz de meses, cada elemento de que es una matriz de días. En el ejemplo se usa una matriz escalonada porque los distintos meses tienen diferentes números de días.
Una matriz escalonada es una matriz unidimensional cuyos elementos contienen matrices. También se pueden asignar valores a los elementos de una matriz escalonada usando literales de matriz anidados. Sin embargo, el intento de usar literales de matriz anidados (por ejemplo, Dim valuesjagged = {{1, 2}, {2, 3, 4}}) genera un error del compilador BC30568. Para corregir el error, incluya los literales de matriz interna entre paréntesis.
Lea también: ¿Cómo localizar tus XML del SAT?
Aunque también puedes anidar literales de matriz que especifican matrices de diferentes longitudes, en el caso de una matriz escalonada, asegúrate de que los literales de matriz anidados están entre paréntesis (()). Los paréntesis fuerzan la evaluación de los literales de matriz anidados y las matrices resultantes se usan como valores iniciales de la matriz irregular. Una matriz escalonada es una matriz cuyos elementos son matrices, posiblemente de diferentes tamaños. Sus elementos son tipos de referencia y se inicializan en null. Debe inicializar los elementos de una matriz escalonada para poder usarlos. Cada uno de los elementos es una matriz. También puede usar inicializadores para rellenar los elementos de matriz con valores.
Arrays Estáticos y Dinámicos
En el apartado correspondiente a declaración de variables, ya hemos tratado la forma de declarar arrays estáticos unidimensionales y multidimensionales a través de la instrucción Dim. Usaremos esta misma instrucción para declarar arrays dinámicos. Un array estático no puede ser redimensionado. En cambio, uno dinámico puede sufrir múltiples redimensionamientos.
Recordemos que habíamos definido array dinámico como aquel que es declarado con un número de elementos componentes indefinido. Es decir, en la cabecera de código del formulario o de un procedimiento haremos una declaración sin especificar dimensiones que luego concretaremos a través de la instrucción ReDim.
Redimensionamiento de Arrays con ReDim
Si tiene una matriz existente, puede redefinir su tamaño mediante la ReDim instrucción. Puede especificar que la ReDim instrucción mantiene los valores que están en la matriz o puede especificar que crea una matriz vacía. Por defecto, el uso de ReDim implicará perder todos los datos anteriormente contenidos en la matriz (array, arreglo) que se redimensiona.
Para conservar los datos anteriores, podemos usar ReDim Preserve. La limitación de usar Preserve viene dada porque únicamente se nos permite cambiar la última dimensión del array (la situada más a la derecha). Tampoco se permite cambiar el número de dimensiones. Cuando se utiliza Preserve aumentando el número de elementos del array, los nuevos elementos tienen valor cero o nulo y los que existían anteriormente conservan su valor. Cuando se trata de una disminución de los elementos de un array, aquellos contenidos en índices que desaparecen dejan de existir a todos los efectos, mientras que los existentes en dimensiones que se conservan mantienen su valor. En caso de arrays de varias dimensiones, con ReDim Preserve sólo podemos cambiar la última dimensión.
Ejemplo: si declaramos un array multidimensional denominado B como Dim B( , , ) As Integer (en versiones menos recientes simplemente Dim B () As Integer), luego redimensionamos ReDim B(4, 2, 6) y posteriormente intentamos hacer ReDim B (2,2,2) obtendremos un mensaje de error ya que sólo puede cambiarse la dimensión más a la derecha. Es decir, ReDim (4, 2, x) donde x es la dimensión cuyo tamaño cambiamos es válido.
Cuando se usa ReDim para redimensionar una matriz, Visual Basic crea una nueva matriz y libera la anterior. Esto tarda tiempo de ejecución.
Borrar y Vaciar Arrays
Una cuestión a tener en cuenta es que la instrucción Erase, cuyo funcionamiento habíamos visto que con matrices estáticas daba lugar a que todos los elementos de la matriz se convirtieran en ceros o cadenas vacías, al ser aplicada a un array dinámico da lugar a que este desaparezca totalmente. Por tanto, no podremos invocar la matriz después de usar Erase a no ser que la declaremos de nuevo usando ReDim nuevamente.
Al igual que en VB6, Erase elimina totalmente el array de la memoria. También se puede asignar un valor Nothing al array. Esto funciona en Visual Basic 2010 pero no en VB6, debido a que en Visual Basic 2010 los arrays son tipos por referencia.
Acceso e Iteración de Arrays
Puede acceder a cada ubicación de una matriz mediante un índice de tipo Integer. Puede almacenar y recuperar valores en una matriz haciendo referencia a cada ubicación de matriz mediante su índice entre paréntesis. Al recorrer en iteración una matriz, se accede a cada elemento de la matriz desde el índice más bajo hasta el más alto o desde el más alto hasta el más bajo. Normalmente, use For...Next Statement o For Each...Next Statement para recorrer los elementos de una matriz. En nuestro post anterior vimos un caso en especial, un bucle ideal para recorrer arreglos llamado For Each.
Cuando 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. El GetUpperBound método tiene un parámetro que especifica la dimensión. El ejemplo siguiente recorre en iteración una matriz multidimensional mediante el uso de una instrucción For...Next.
Para acceder a los elementos del array multidimensional lo hacemos exactamente de la misma forma que accedemos en el array normal. El tener que Acceder por dos índices genera que la forma de recorrer el array sea algo diferente.
Propiedades e Información de Arrays
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. Puede encontrar el tamaño de una matriz mediante la Array.Length propiedad.
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.
Cada matriz tiene un tipo de datos, que difiere del tipo de datos de sus elementos. No hay ningún tipo de datos único para todas las matrices. En su lugar, el tipo de datos de una matriz viene determinado por 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 la misma clasificación y sus elementos tienen el mismo tipo de datos.
Puede llamar al método GetType de la variable para obtener un objeto Type que representa el tipo en tiempo de ejecución de la variable. En el ejemplo siguiente se llama al GetType método y a la TypeName función para determinar el tipo de una matriz. El tipo de matriz es Byte(,).
La longitud de cada dimensión de una matriz se limita al valor máximo del Integer tipo de 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. El tamaño de una matriz es independiente del tipo de datos de sus elementos. No es seguro realizar ninguna suposición sobre cómo se almacena una matriz en la memoria. El almacenamiento varía en plataformas de anchos de datos diferentes, por lo que la misma matriz puede consumir más memoria en un sistema de 64 bits que en un sistema de 32 bits. En función de la configuración del sistema al inicializar una matriz, Common Language Runtime (CLR) puede asignar almacenamiento para empaquetar los elementos lo más cerca posible, o para alinearlos todos en límites de hardware natural.
Arrays como Parámetros y Valores de Retorno
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 Instruction Function. Dentro de la función, declare una variable de matriz local con el mismo tipo de datos y número de dimensiones.
Para especificar una matriz como parámetro para un Sub procedimiento o Function, defina el parámetro como una matriz con un tipo de datos especificado y el número de dimensiones. En el ejemplo siguiente, la función GetNumbers devuelve un Integer(), una matriz unidimensional de tipo Integer. En el ejemplo siguiente, la función GetNumbersMultiDim devuelve una Integer(,), una matriz bidimensional de tipo Integer.
Puede pasar una matriz unidimensional inicializada a un método. En el ejemplo siguiente, una matriz de cadenas se inicializa y pasa como un argumento a un método DisplayArray para cadenas. El método muestra los elementos de la matriz. Pase una matriz multidimensional inicializada a un método de la misma manera que pasa una matriz unidimensional. En el código siguiente, se muestra una declaración parcial de un método de impresión que acepta una matriz bidimensional como su argumento. Puede inicializar y pasar una nueva matriz en un paso.
Manipulación de Arrays: Dividir y Combinar
En algunos casos, es posible que tenga que dividir una sola matriz en varias matrices. Puede que desee dividir una matriz de más de un número especificado de elementos en un número aproximado de partes iguales. En el ejemplo siguiente se divide una matriz en dos matrices de tamaño aproximado igual. También puede ser útil un valor de un elemento que actúa como delimitador que indica dónde se debe dividir la matriz. 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 matriz.
También puede combinar una serie de matrices en una sola matriz mayor. 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 acomodar la nueva matriz. Use la ReDim Preserve instrucción para expandir dinámicamente la matriz antes de agregarle nuevos elementos. 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.
Arrays vs. Colecciones
Las matrices son más ú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. Si la colección contiene solo elementos de un tipo de datos, puede usar una de las clases del System.Collections.Generic espacio de nombres.
Cuando programamos, una de las funcionalidades que más se utilizan son las colecciones de datos, ya sean estas desde una base de datos, desde un servicio externo o creadas por nosotros mismos. En este tutorial veremos cómo trabajar con este tipo de datos, no creamos una variable para cada uno de los empleados o alumnos, sino que creamos una estructura de datos llamada colecciones. Otra de las características que contienen los arrays es que no tienen límite de tamaño y puede contener tantos registros como queramos siempre y cuando tengamos memoria suficiente en el ordenador. Finalmente, los arrays son Inmutables, lo que quiere decir que una vez los inicializamos estos no cambian.
Arrays en C#
En C#, una matriz es un tipo de referencia, por lo que la matriz puede ser un tipo de referencia que acepta valores NULL. Los tipos de elemento pueden ser tipos de referencia, por lo que puede declarar una matriz para contener tipos de referencia que aceptan valores NULL. Por ejemplo: type[]? o type?[]?. En el ejemplo anterior, aunque el tipo es string[], una matriz de cadenas que no aceptan valores NULL, el valor predeterminado para cada elemento es NULL.
El número de dimensiones se establece al declarar una variable de matriz. La longitud de cada dimensión se establece al crear la instancia de matriz. Los tipos de matriz son tipos de referencia que proceden del tipo base abstracto Array. Todas las matrices implementan IList e IEnumerable. Puede usar la instrucción foreach para recorrer en iteración una matriz.
Puede inicializar los elementos de una matriz en valores conocidos al crear la matriz. A partir de C# 12, puede usar una expresión Collection para inicializar todos los tipos de colección. Los elementos que no se inicializan se establecen en el valor predeterminado. El valor predeterminado es el patrón de 0 bits. Todos los tipos de referencia (incluidos los tipos que no aceptan valores NULL) tienen el valor null. Todos los tipos de valor tienen los patrones de 0 bits. Esto significa que la propiedad Nullable
Muchos de los ejemplos de este artículo usan expresiones de colección (que usan corchetes) para inicializar las matrices. Las expresiones de colección se introdujeron por primera vez en C# 12, incorporado con .NET 8. Se crea una matriz unidimensional mediante el nuevo operador y se especifica el tipo de elemento de matriz y el número de elementos. La primera declaración declara una matriz sin inicializar de cinco enteros, de array[0] a array[4]. Los elementos de la matriz se inicializan en el valor predeterminado del tipo de elemento, 0 para los enteros. La segunda declaración declara una matriz de cadenas e inicializa los siete valores de esa matriz.
Puede crear una matriz con tipo implícito en la que se deduce el tipo de la instancia de matriz de los elementos especificados en el inicializador de matriz. Las reglas de cualquier variable de tipo implícito también se aplican a las matrices de tipo implícito. En el ejemplo anterior, observe que, con las matrices de tipo implícito, no se usan corchetes en el lado izquierdo de la instrucción de inicialización. Al crear un tipo anónimo que contiene una matriz, esta debe tener tipo implícito en el inicializador de objeto del tipo. En el ejemplo siguiente, contacts es una matriz de tipo implícito de tipos anónimos, cada uno de los cuales contiene una matriz denominada PhoneNumbers.
