Módulo 05: Arrays

Objetivos del módulo

  • Entender qué es un array y por qué se necesita
  • Crear y manipular arrays unidimensionales
  • Trabajar con arrays multidimensionales y jagged arrays
  • Conocer los métodos más útiles de la clase Array
  • Recorrer arrays con for y foreach

1. ¿Qué es un array?

📘 Concepto: Un array (arreglo) es una estructura de datos que almacena una colección de elementos del mismo tipo en posiciones consecutivas de memoria. Piensa en un array como una estantería con casillas numeradas: cada casilla tiene un número (índice) y puede guardar un valor.

Índice:    [0]      [1]      [2]      [3]      [4]
         ┌────────┬────────┬────────┬────────┬────────┐
notas:   │  7.5   │  8.0   │  6.5   │  9.0   │  5.5   │
         └────────┴────────┴────────┴────────┴────────┘

⚠️ Importante: En C# (y en la mayoría de lenguajes), los índices de un array empiezan en 0, no en 1. El primer elemento es array[0], el segundo es array[1], etc.


2. Declaración e inicialización

Forma 1: Declarar y luego asignar valores

// Declarar un array de 5 enteros (todos valen 0 inicialmente)
int[] numeros = new int[5];

// Asignar valores individual por posición
numeros[0] = 10;
numeros[1] = 20;
numeros[2] = 30;
numeros[3] = 40;
numeros[4] = 50;

Console.WriteLine(numeros[0]);  // 10
Console.WriteLine(numeros[2]);  // 30
Console.WriteLine(numeros[4]);  // 50

Explicación:

Código Explicación
int[] Declara que es un array de enteros. Los [] indican “array”.
new int[5] Crea un array con 5 posiciones (índices 0 a 4).
numeros[0] = 10 Asigna el valor 10 a la posición 0.

Forma 2: Declarar e inicializar a la vez

// Forma larga
int[] numeros = new int[] { 10, 20, 30, 40, 50 };

// Forma abreviada (recomendada)
int[] numeros2 = { 10, 20, 30, 40, 50 };

// Forma moderna con new[] (el compilador infiere el tipo)
var numeros3 = new[] { 10, 20, 30, 40, 50 };

// Arrays de otros tipos
string[] nombres = { "Ana", "Luis", "María", "Pedro" };
double[] precios = { 9.99, 15.50, 3.25, 7.80 };
bool[] respuestas = { true, false, true, true };

Valores por defecto

Cuando creas un array sin asignar valores, cada posición tiene un valor por defecto:

Tipo Valor por defecto
int, long, etc. 0
double, float 0.0
bool false
char '\0' (carácter nulo)
string null

3. Acceso y modificación de elementos

string[] frutas = { "Manzana", "Banana", "Cereza", "Dátil", "Fresa" };

// Leer elementos
Console.WriteLine(frutas[0]);   // "Manzana" (primer elemento)
Console.WriteLine(frutas[2]);   // "Cereza" (tercer elemento)
Console.WriteLine(frutas[4]);   // "Fresa" (último elemento)

// Modificar elementos
frutas[1] = "Naranja";  // Cambia "Banana" por "Naranja"
Console.WriteLine(frutas[1]);   // "Naranja"

// Obtener la longitud del array
Console.WriteLine($"El array tiene {frutas.Length} elementos");  // 5

// Acceder al último elemento
Console.WriteLine($"Último: {frutas[frutas.Length - 1]}");  // "Fresa"

// Forma moderna: índice desde el final con ^
Console.WriteLine($"Último: {frutas[^1]}");    // "Fresa"
Console.WriteLine($"Penúltimo: {frutas[^2]}"); // "Dátil"

⚠️ Importante: Si intentas acceder a un índice fuera del rango, obtendrás un error IndexOutOfRangeException:

int[] numeros = { 1, 2, 3 };
// Console.WriteLine(numeros[5]);  // ❌ ERROR: IndexOutOfRangeException
// Console.WriteLine(numeros[-1]); // ❌ ERROR: IndexOutOfRangeException

4. Recorrer un array

Con for

int[] numeros = { 10, 20, 30, 40, 50 };

// Recorrer con for
for (int i = 0; i < numeros.Length; i++)
{
    Console.WriteLine($"numeros[{i}] = {numeros[i]}");
}

Salida:

numeros[0] = 10
numeros[1] = 20
numeros[2] = 30
numeros[3] = 40
numeros[4] = 50

Con foreach

string[] nombres = { "Ana", "Luis", "María" };

foreach (string nombre in nombres)
{
    Console.WriteLine($"Hola, {nombre}!");
}

¿for o foreach?

Usa for Usa foreach
Necesitas el índice Solo necesitas el valor
Quieres modificar elementos Solo quieres leer elementos
Quieres recorrer parcialmente Quieres recorrer todo el array

5. Operaciones con arrays: Rangos y slices

C# moderno permite extraer partes de un array con la sintaxis de rangos:

int[] numeros = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

// Subarray desde índice 2 hasta 5 (sin incluir 5)
int[] parte = numeros[2..5];    // { 2, 3, 4 }

// Desde el inicio hasta el índice 3
int[] inicio = numeros[..3];    // { 0, 1, 2 }

// Desde el índice 7 hasta el final
int[] final2 = numeros[7..];     // { 7, 8, 9 }

// Los últimos 3 elementos
int[] ultimos = numeros[^3..];  // { 7, 8, 9 }

// Mostrar
Console.WriteLine($"parte: {string.Join(", ", parte)}");
Console.WriteLine($"inicio: {string.Join(", ", inicio)}");
Console.WriteLine($"final: {string.Join(", ", final2)}");
Console.WriteLine($"últimos 3: {string.Join(", ", ultimos)}");

6. Métodos útiles de la clase Array

int[] numeros = { 5, 3, 8, 1, 9, 2, 7, 4, 6 };

// Ordenar
Array.Sort(numeros);
Console.WriteLine($"Ordenado: {string.Join(", ", numeros)}");
// 1, 2, 3, 4, 5, 6, 7, 8, 9

// Invertir
Array.Reverse(numeros);
Console.WriteLine($"Invertido: {string.Join(", ", numeros)}");
// 9, 8, 7, 6, 5, 4, 3, 2, 1

// Buscar un elemento
int indice = Array.IndexOf(numeros, 5);
Console.WriteLine($"El 5 está en el índice: {indice}");

// Verificar si existe
bool existe = Array.Exists(numeros, n => n == 7);
Console.WriteLine($"¿Existe el 7? {existe}");  // True

// Encontrar un elemento que cumpla una condición
int primerPar = Array.Find(numeros, n => n % 2 == 0);
Console.WriteLine($"Primer par: {primerPar}");

// Rellenar con un valor
int[] ceros = new int[5];
Array.Fill(ceros, 99);
Console.WriteLine($"Rellenado: {string.Join(", ", ceros)}");
// 99, 99, 99, 99, 99

// Copiar un array
int[] copia = new int[numeros.Length];
Array.Copy(numeros, copia, numeros.Length);

// Limpiar (poner a valor por defecto)
Array.Clear(copia);
Console.WriteLine($"Limpiado: {string.Join(", ", copia)}");
// 0, 0, 0, 0, 0, 0, 0, 0, 0

7. Arrays multidimensionales

Array bidimensional (matriz)

Un array de dos dimensiones es como una tabla con filas y columnas:

         Col 0   Col 1   Col 2
       ┌───────┬───────┬───────┐
Fila 0 │   1   │   2   │   3   │
       ├───────┼───────┼───────┤
Fila 1 │   4   │   5   │   6   │
       ├───────┼───────┼───────┤
Fila 2 │   7   │   8   │   9   │
       └───────┴───────┴───────┘
// Declarar una matriz 3x3
int[,] matriz = new int[3, 3];

// Asignar valores
matriz[0, 0] = 1; matriz[0, 1] = 2; matriz[0, 2] = 3;
matriz[1, 0] = 4; matriz[1, 1] = 5; matriz[1, 2] = 6;
matriz[2, 0] = 7; matriz[2, 1] = 8; matriz[2, 2] = 9;

// Forma directa
int[,] matriz2 = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

// Recorrer con bucles anidados
int filas = matriz2.GetLength(0);     // 3 filas
int columnas = matriz2.GetLength(1);  // 3 columnas

for (int i = 0; i < filas; i++)
{
    for (int j = 0; j < columnas; j++)
    {
        Console.Write($"{matriz2[i, j],4}");
    }
    Console.WriteLine();
}

Salida:

   1   2   3
   4   5   6
   7   8   9

Ejemplo práctico: Notas de alumnos

// 3 alumnos, 4 asignaturas
double[,] notas = {
    { 7.5, 8.0, 6.5, 9.0 },   // Alumno 0
    { 5.0, 6.5, 7.0, 8.5 },   // Alumno 1
    { 9.0, 9.5, 8.0, 10.0 }   // Alumno 2
};
string[] alumnos = { "Ana", "Luis", "María" };
string[] asignaturas = { "Mates", "Lengua", "Inglés", "Ciencias" };

for (int i = 0; i < alumnos.Length; i++)
{
    double suma = 0;
    for (int j = 0; j < asignaturas.Length; j++)
    {
        suma += notas[i, j];
    }
    double media = suma / asignaturas.Length;
    Console.WriteLine($"{alumnos[i],-8} | Media: {media:F2}");
}

8. Jagged arrays (arrays dentados)

Un jagged array es un array de arrays, donde cada fila puede tener un tamaño diferente:

// Cada fila puede tener distinto número de elementos
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 3, 4, 5, 6 };
jagged[2] = new int[] { 7 };

// Forma directa
int[][] jagged2 = {
    new[] { 1, 2 },
    new[] { 3, 4, 5, 6 },
    new[] { 7 }
};

// Recorrer
for (int i = 0; i < jagged2.Length; i++)
{
    Console.Write($"Fila {i}: ");
    for (int j = 0; j < jagged2[i].Length; j++)
    {
        Console.Write($"{jagged2[i][j]} ");
    }
    Console.WriteLine();
}

Salida:

Fila 0: 1 2
Fila 1: 3 4 5 6
Fila 2: 7

9. Arrays como parámetros y retorno de funciones

// Función que recibe un array y devuelve la suma
int Sumar(int[] numeros)
{
    int total = 0;
    foreach (int n in numeros)
    {
        total += n;
    }
    return total;
}

// Función que devuelve un array
int[] GenerarPares(int cantidad)
{
    int[] pares = new int[cantidad];
    for (int i = 0; i < cantidad; i++)
    {
        pares[i] = (i + 1) * 2;
    }
    return pares;
}

// Uso
int[] misNumeros = { 10, 20, 30, 40 };
Console.WriteLine($"Suma: {Sumar(misNumeros)}");  // 100

int[] primerosPares = GenerarPares(5);
Console.WriteLine($"Pares: {string.Join(", ", primerosPares)}");
// 2, 4, 6, 8, 10

10. Ejercicios

Ejercicio 1: Media de notas

Pide al usuario cuántas notas quiere introducir, lee las notas y calcula la media, la nota más alta y la más baja.

Ejercicio 2: Buscar un elemento

Crea un array de 10 nombres. Pide al usuario un nombre y busca si existe en el array. Si existe, muestra en qué posición.

Ejercicio 3: Array invertido

Dado un array de números, crea un nuevo array con los elementos en orden inverso (sin usar Array.Reverse()).

Ejercicio 4: Eliminar duplicados

Dado el array { 1, 2, 3, 2, 4, 3, 5, 1, 6 }, crea un nuevo array sin duplicados.

Pista: Puedes usar Array.IndexOf() para comprobar si un elemento ya está en el resultado.

Ejercicio 5: Tablero de ajedrez

Representa un tablero de ajedrez 8x8 como un array bidimensional de char. Inicializa la posición inicial de las piezas y muéstralo por pantalla:

♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖

Resumen

Concepto Sintaxis Ejemplo
Declarar tipo[] nombre = new tipo[tamaño] int[] nums = new int[5]
Inicializar tipo[] nombre = { valores } int[] nums = { 1, 2, 3 }
Acceder nombre[índice] nums[0] → primer elemento
Longitud nombre.Length nums.Length → 3
Último nombre[^1] nums[^1] → último
Rango nombre[inicio..fin] nums[1..3] → subarray
Ordenar Array.Sort(array) Ordena in-place
Buscar Array.IndexOf(array, val) Devuelve índice o -1
Matriz tipo[,] nombre int[,] m = new int[3,3]
Jagged tipo[][] nombre int[][] j = new int[3][]