C# Language
Arrays
Buscar..
Sintaxis
Declarar una matriz:
<tipo> [] <nombre>;
Declarando matriz bidimensional:
<tipo> [,] <nombre> = nuevo <tipo> [<valor>, <valor>];
Declarar una matriz irregular:
<tipo> [] <nombre> = nuevo <tipo> [<valor>];
Declarar un subarreglo para una matriz irregular:
<nombre> [<valor>] = nuevo <tipo> [<valor>];
Inicializando una matriz sin valores:
<nombre> = nuevo <tipo> [<longitud>];
Inicializando una matriz con valores:
<nombre> = nuevo <tipo> [] {<valor>, <valor>, <valor>, ...};
Inicializando una matriz bidimensional con valores:
<nombre> = nuevo <tipo> [,] {{<valor>, <valor>}, {<valor>, <valor>}, ...};
Accediendo a un elemento en el índice i:
<nombre> [i]
Obtención de la longitud de la matriz:
<nombre> .Longitud
Observaciones
En C #, una matriz es un tipo de referencia, lo que significa que es anulable .
Una matriz tiene una longitud fija, lo que significa que no puede .Add()
a ella o .Remove()
de ella. Para utilizar estos, necesitaría una matriz dinámica: List
o ArrayList
.
Covarianza Array
string[] strings = new[] {"foo", "bar"};
object[] objects = strings; // implicit conversion from string[] to object[]
Esta conversión no es de tipo seguro. El siguiente código generará una excepción de tiempo de ejecución:
string[] strings = new[] {"Foo"};
object[] objects = strings;
objects[0] = new object(); // runtime exception, object is not string
string str = strings[0]; // would have been bad if above assignment had succeeded
Obtención y configuración de valores de matriz
int[] arr = new int[] { 0, 10, 20, 30};
// Get
Console.WriteLine(arr[2]); // 20
// Set
arr[2] = 100;
// Get the updated value
Console.WriteLine(arr[2]); // 100
Declarando una matriz
Una matriz se puede declarar y rellenar con el valor predeterminado utilizando la sintaxis de inicialización entre corchetes ( []
). Por ejemplo, creando una matriz de 10 enteros:
int[] arr = new int[10];
Los índices en C # están basados en cero. Los índices de la matriz anterior serán 0-9. Por ejemplo:
int[] arr = new int[3] {7,9,4};
Console.WriteLine(arr[0]); //outputs 7
Console.WriteLine(arr[1]); //outputs 9
Lo que significa que el sistema comienza a contar el índice de elementos desde 0. Además, los accesos a los elementos de las matrices se realizan en un tiempo constante . Eso significa que acceder al primer elemento de la matriz tiene el mismo costo (en el tiempo) de acceder al segundo elemento, al tercer elemento y así sucesivamente.
También puede declarar una referencia simple a una matriz sin crear una instancia de una matriz.
int[] arr = null; // OK, declares a null reference to an array.
int first = arr[0]; // Throws System.NullReferenceException because there is no actual array.
Una matriz también se puede crear e inicializar con valores personalizados utilizando la sintaxis de inicialización de la colección:
int[] arr = new int[] { 24, 2, 13, 47, 45 };
La new int[]
porción new int[]
se puede omitir cuando se declara una variable de matriz. Esta no es una expresión independiente, por lo que usarla como parte de una llamada diferente no funciona (para eso, usa la versión con la new
):
int[] arr = { 24, 2, 13, 47, 45 }; // OK
int[] arr1;
arr1 = { 24, 2, 13, 47, 45 }; // Won't compile
Arrays implícitamente escritos
Alternativamente, en combinación con la palabra clave var
, el tipo específico se puede omitir para que se infiera el tipo de la matriz:
// same as int[]
var arr = new [] { 1, 2, 3 };
// same as string[]
var arr = new [] { "one", "two", "three" };
// same as double[]
var arr = new [] { 1.0, 2.0, 3.0 };
Iterar sobre una matriz
int[] arr = new int[] {1, 6, 3, 3, 9};
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
utilizando foreach:
foreach (int element in arr)
{
Console.WriteLine(element);
}
Uso de acceso no seguro con punteros https://msdn.microsoft.com/en-ca/library/y31yhkeb.aspx
unsafe
{
int length = arr.Length;
fixed (int* p = arr)
{
int* pInt = p;
while (length-- > 0)
{
Console.WriteLine(*pInt);
pInt++;// move pointer to next element
}
}
}
Salida:
1
6
3
3
9
Matrices multidimensionales
Las matrices pueden tener más de una dimensión. El siguiente ejemplo crea una matriz bidimensional de diez filas y diez columnas:
int[,] arr = new int[10, 10];
Una matriz de tres dimensiones:
int[,,] arr = new int[10, 10, 10];
También puede inicializar la matriz tras la declaración:
int[,] arr = new int[4, 2] { {1, 1}, {2, 2}, {3, 3}, {4, 4} };
// Access a member of the multi-dimensional array:
Console.Out.WriteLine(arr[3, 1]); // 4
Matrices dentadas
Las matrices irregulares son matrices que, en lugar de tipos primitivos, contienen matrices (u otras colecciones). Es como una matriz de matrices: cada elemento de matriz contiene otra matriz.
Son similares a las matrices multidimensionales, pero tienen una ligera diferencia: como las matrices multidimensionales se limitan a un número fijo de filas y columnas, con matrices irregulares, cada fila puede tener un número diferente de columnas.
Declarar una matriz irregular
Por ejemplo, declarando una matriz irregular con 8 columnas:
int[][] a = new int[8][];
El segundo []
se inicializa sin un número. Para inicializar las matrices secundarias, tendría que hacerlo por separado:
for (int i = 0; i < a.length; i++)
{
a[i] = new int[10];
}
Obtención / Configuración de valores
Ahora, obtener uno de los subarrays es fácil. Imprimamos todos los números de la tercera columna de a
:
for (int i = 0; i < a[2].length; i++)
{
Console.WriteLine(a[2][i]);
}
Obteniendo un valor específico:
a[<row_number>][<column_number>]
Establecer un valor específico:
a[<row_number>][<column_number>] = <value>
Recuerde : siempre se recomienda utilizar matrices dentadas (matrices de matrices) en lugar de matrices multidimensionales (matrices). Es más rápido y seguro de usar.
Nota sobre el orden de los corchetes.
Considere una matriz tridimensional de matrices de cinco dimensiones de matrices unidimensionales de int
. Esto está escrito en C # como:
int[,,][,,,,][] arr = new int[8, 10, 12][,,,,][];
En el sistema de tipos de CLR, el Convenio para la ordenación de los soportes se invierte, por lo que con lo anterior arr
ejemplo tenemos:
arr.GetType().ToString() == "System.Int32[][,,,,][,,]"
y de la misma manera:
typeof(int[,,][,,,,][]).ToString() == "System.Int32[][,,,,][,,]"
Comprobando si una matriz contiene otra matriz
public static class ArrayHelpers
{
public static bool Contains<T>(this T[] array, T[] candidate)
{
if (IsEmptyLocate(array, candidate))
return false;
if (candidate.Length > array.Length)
return false;
for (int a = 0; a <= array.Length - candidate.Length; a++)
{
if (array[a].Equals(candidate[0]))
{
int i = 0;
for (; i < candidate.Length; i++)
{
if (false == array[a + i].Equals(candidate[i]))
break;
}
if (i == candidate.Length)
return true;
}
}
return false;
}
static bool IsEmptyLocate<T>(T[] array, T[] candidate)
{
return array == null
|| candidate == null
|| array.Length == 0
|| candidate.Length == 0
|| candidate.Length > array.Length;
}
}
/// Muestra
byte[] EndOfStream = Encoding.ASCII.GetBytes("---3141592---");
byte[] FakeReceivedFromStream = Encoding.ASCII.GetBytes("Hello, world!!!---3141592---");
if (FakeReceivedFromStream.Contains(EndOfStream))
{
Console.WriteLine("Message received");
}
Inicializando una matriz llena con un valor no predeterminado repetido
Como sabemos, podemos declarar una matriz con valores predeterminados:
int[] arr = new int[10];
Esto creará una matriz de 10 enteros con cada elemento de la matriz que tiene el valor 0
(el valor predeterminado de tipo int
).
Para crear una matriz inicializada con un valor no predeterminado, podemos usar Enumerable.Repeat
desde el espacio de nombres System.Linq
:
Para crear una matriz
bool
de tamaño 10 rellena con "true"bool[] booleanArray = Enumerable.Repeat(true, 10).ToArray();
Para crear una matriz
int
de tamaño 5 rellena con "100"int[] intArray = Enumerable.Repeat(100, 5).ToArray();
Para crear una matriz de
string
de tamaño 5 rellena con "C #"string[] strArray = Enumerable.Repeat("C#", 5).ToArray();
Copiando matrices
Copiando una matriz parcial con el Array.Copy()
estático Array.Copy()
, comenzando en el índice 0 tanto en el origen como en el destino:
var sourceArray = new int[] { 11, 12, 3, 5, 2, 9, 28, 17 };
var destinationArray= new int[3];
Array.Copy(sourceArray, destinationArray, 3);
// destinationArray will have 11,12 and 3
Copiando toda la matriz con el método de instancia CopyTo()
, comenzando en el índice 0 del origen y el índice especificado en el destino:
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = new int[6];
sourceArray.CopyTo(destinationArray, 2);
// destinationArray will have 0, 0, 11, 12, 7 and 0
Clone
se utiliza para crear una copia de un objeto de matriz.
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = (int)sourceArray.Clone();
//destinationArray will be created and will have 11,12,17.
Tanto CopyTo
como Clone
realizan una copia superficial, lo que significa que el contenido contiene referencias al mismo objeto que los elementos de la matriz original.
Creando una matriz de números secuenciales
LINQ proporciona un método que facilita la creación de una colección con números secuenciales. Por ejemplo, puede declarar una matriz que contiene los números enteros entre 1 y 100.
El método Enumerable.Range
nos permite crear una secuencia de números enteros desde una posición de inicio especificada y una serie de elementos.
El método toma dos argumentos: el valor de inicio y el número de elementos a generar.
Enumerable.Range(int start, int count)
Tenga en count
que la count
no puede ser negativa.
Uso:
int[] sequence = Enumerable.Range(1, 100).ToArray();
Esto generará una matriz que contiene los números del 1 al 100 ( [1, 2, 3, ..., 98, 99, 100]
).
Debido a que el método Range
devuelve un IEnumerable<int>
, podemos usar otros métodos LINQ en él:
int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray();
Esto generará una matriz que contiene 10 cuadrados enteros comenzando en 4
: [4, 9, 16, ..., 100, 121]
.
Comparando matrices para la igualdad
LINQ proporciona una función incorporada para verificar la igualdad de dos IEnumerable
s, y esa función se puede usar en arreglos.
La función SequenceEqual
devolverá true
si las matrices tienen la misma longitud y los valores en los índices correspondientes son iguales, y false
contrario.
int[] arr1 = { 3, 5, 7 };
int[] arr2 = { 3, 5, 7 };
bool result = arr1.SequenceEqual(arr2);
Console.WriteLine("Arrays equal? {0}", result);
Esto imprimirá:
Arrays equal? True
Arreglos como instancias IEnumerable <>
Todas las matrices implementan la interfaz IList
no genérica (y, por lo tanto, las interfaces de base ICollection
y IEnumerable
no genéricas).
Más importante aún, las matrices unidimensionales implementan las interfaces genéricas IList<>
e IReadOnlyList<>
(y sus interfaces base) para el tipo de datos que contienen. Esto significa que pueden tratarse como tipos enumerables genéricos y pasarse a una variedad de métodos sin necesidad de convertirlos primero a una forma no de matriz.
int[] arr1 = { 3, 5, 7 };
IEnumerable<int> enumerableIntegers = arr1; //Allowed because arrays implement IEnumerable<T>
List<int> listOfIntegers = new List<int>();
listOfIntegers.AddRange(arr1); //You can pass in a reference to an array to populate a List.
Después de ejecutar este código, la lista listOfIntegers
contendrá una List<int>
contiene los valores 3, 5 y 7.
La IEnumerable<>
significa que las matrices se pueden consultar con LINQ, por ejemplo, arr1.Select(i => 10 * i)
.