Volver al curso

JavaScript Desde Cero: Tu Primer Lenguaje de Programación

leccion
11 / 22
beginner
8 horas
Arrays, Objetos y el DOM

Arrays en Profundidad: Creación, Métodos y Patrones

Lectura
40 min~9 min lectura

Arrays en Profundidad: Creación, Métodos y Patrones

Objetivos de aprendizaje

Al finalizar esta lección serás capaz de:

  • Crear arrays de diferentes formas y entender su estructura interna
  • Dominar los métodos mutables e inmutables de arrays
  • Aplicar técnicas de desestructuración y spread con arrays
  • Resolver problemas comunes usando arrays como estructura de datos principal
  • Identificar cuándo usar arrays vs otras estructuras de datos

1. Creación y estructura de arrays

Un array es una colección ordenada de elementos. Es la estructura de datos más utilizada en JavaScript y dominarla es fundamental para cualquier desarrollador.

Formas de crear arrays

// Literal (más común y recomendado)
const frutas = ["manzana", "banana", "cereza"];
const numeros = [1, 2, 3, 4, 5];
const mixto = ["texto", 42, true, null, { nombre: "Ana" }];
const vacio = [];

// Constructor Array (menos usado)
const arr1 = new Array(5);       // [empty × 5] (5 espacios vacíos)
const arr2 = new Array(1, 2, 3); // [1, 2, 3]

// Array.from() — crear desde otro iterable
const letras = Array.from("Hola"); // ["H", "o", "l", "a"]
const rango = Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5]
const pares = Array.from({ length: 10 }, (_, i) => (i + 1) * 2); // [2, 4, 6, ..., 20]

// Array.of() — crear con elementos específicos
const arr3 = Array.of(5); // [5] (no confundir con new Array(5))

// Spread para combinar arrays
const a = [1, 2, 3];
const b = [4, 5, 6];
const combinado = [...a, ...b]; // [1, 2, 3, 4, 5, 6]

// Fill — rellenar con un valor
const ceros = new Array(10).fill(0); // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
const tablero = new Array(3).fill(null).map(() => new Array(3).fill("-"));
// [["-","-","-"], ["-","-","-"], ["-","-","-"]]

Acceso y modificación de elementos

const colores = ["rojo", "verde", "azul", "amarillo"];

// Acceder por índice (empieza en 0)
console.log(colores[0]);  // "rojo"
console.log(colores[2]);  // "azul"
console.log(colores[10]); // undefined (no da error)

// Acceso desde el final con at()
console.log(colores.at(-1)); // "amarillo" (último)
console.log(colores.at(-2)); // "azul" (penúltimo)

// Modificar un elemento
colores[1] = "púrpura";
console.log(colores); // ["rojo", "púrpura", "azul", "amarillo"]

// Longitud
console.log(colores.length); // 4

// Desestructuración
const [primero, segundo, ...resto] = colores;
console.log(primero); // "rojo"
console.log(segundo); // "púrpura"
console.log(resto);   // ["azul", "amarillo"]

// Swap (intercambiar) con desestructuración
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1

Métodos que MUTAN el array original

const arr = [3, 1, 4, 1, 5];

// push() - agregar al final
arr.push(9);           // [3, 1, 4, 1, 5, 9]
arr.push(2, 6);        // [3, 1, 4, 1, 5, 9, 2, 6]

// pop() - quitar del final
const ultimo = arr.pop(); // 6, arr = [3, 1, 4, 1, 5, 9, 2]

// unshift() - agregar al inicio
arr.unshift(0);        // [0, 3, 1, 4, 1, 5, 9, 2]

// shift() - quitar del inicio
const primero = arr.shift(); // 0, arr = [3, 1, 4, 1, 5, 9, 2]

// splice(inicio, cantidadAQuitar, ...elementosAInsertar)
arr.splice(2, 1);      // Quitar 1 elemento desde posición 2
arr.splice(1, 0, 99);  // Insertar 99 en posición 1 (sin quitar nada)

// sort() - ordenar
arr.sort((a, b) => a - b); // Ascendente

// reverse() - invertir
arr.reverse();

// fill() - rellenar
const arr2 = [1, 2, 3, 4, 5];
arr2.fill(0, 2, 4); // [1, 2, 0, 0, 5] (rellenar posiciones 2 a 3)

Métodos que NO mutan (retornan nuevo array)

const original = [1, 2, 3, 4, 5];

// concat() - combinar
const combinado = original.concat([6, 7], [8]); // [1,2,3,4,5,6,7,8]

// slice(inicio, fin) - extraer porción
const porcion = original.slice(1, 4); // [2, 3, 4]
const copia = original.slice();        // [1, 2, 3, 4, 5] (copia completa)

// Nuevos métodos inmutables (ES2023+)
const ordenado = original.toSorted((a, b) => b - a); // [5, 4, 3, 2, 1]
const invertido = original.toReversed();  // [5, 4, 3, 2, 1]
const spliced = original.toSpliced(2, 1, 99); // [1, 2, 99, 4, 5]

// El original NUNCA cambia
console.log(original); // [1, 2, 3, 4, 5]

2. Patrones comunes con arrays

Eliminar duplicados

const conDuplicados = [1, 2, 2, 3, 3, 3, 4, 5, 5];

// Con Set (más elegante)
const unicos = [...new Set(conDuplicados)];
console.log(unicos); // [1, 2, 3, 4, 5]

// Con filter
const unicosFilter = conDuplicados.filter((item, index, arr) => 
  arr.indexOf(item) === index
);

// Duplicados de objetos (por propiedad)
const usuarios = [
  { id: 1, nombre: "Ana" },
  { id: 2, nombre: "Carlos" },
  { id: 1, nombre: "Ana" },
];

const unicosPorId = usuarios.filter((u, i, arr) =>
  arr.findIndex(x => x.id === u.id) === i
);

Aplanar arrays anidados

const anidado = [[1, 2], [3, [4, 5]], [6]];

console.log(anidado.flat());          // [1, 2, 3, [4, 5], 6]
console.log(anidado.flat(Infinity));  // [1, 2, 3, 4, 5, 6]

// flatMap: map + flat en un paso
const frases = ["hola mundo", "JavaScript genial"];
const palabras = frases.flatMap(f => f.split(" "));
console.log(palabras); // ["hola", "mundo", "JavaScript", "genial"]

Chunks (dividir en grupos)

function dividirEnGrupos(array, tamaño) {
  const grupos = [];
  for (let i = 0; i < array.length; i += tamaño) {
    grupos.push(array.slice(i, i + tamaño));
  }
  return grupos;
}

const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(dividirEnGrupos(nums, 3));
// [[1,2,3], [4,5,6], [7,8,9], [10]]

Zip (combinar arrays paralelos)

function zip(...arrays) {
  const longitud = Math.min(...arrays.map(a => a.length));
  return Array.from({ length: longitud }, (_, i) =>
    arrays.map(a => a[i])
  );
}

const nombres = ["Ana", "Carlos", "María"];
const edades = [28, 35, 22];
const ciudades = ["Buenos Aires", "Lima", "México"];

console.log(zip(nombres, edades, ciudades));
// [["Ana", 28, "Buenos Aires"], ["Carlos", 35, "Lima"], ["María", 22, "México"]]

3. Arrays en el mundo real

Procesamiento de datos de API

// Datos que podrían venir de una API
const respuestaAPI = {
  usuarios: [
    { id: 1, nombre: "Ana García", email: "[email protected]", plan: "premium", activo: true },
    { id: 2, nombre: "Carlos López", email: "[email protected]", plan: "free", activo: true },
    { id: 3, nombre: "María Pérez", email: "[email protected]", plan: "premium", activo: false },
    { id: 4, nombre: "Luis Rodríguez", email: "[email protected]", plan: "pro", activo: true },
    { id: 5, nombre: "Elena Torres", email: "[email protected]", plan: "free", activo: true },
  ]
};

const { usuarios } = respuestaAPI;

// 1. Usuarios premium activos
const premiumActivos = usuarios
  .filter(u => u.plan === "premium" && u.activo)
  .map(u => u.nombre);
console.log("Premium activos:", premiumActivos); // ["Ana García"]

// 2. Conteo por plan
const conteoPorPlan = usuarios.reduce((acc, u) => {
  acc[u.plan] = (acc[u.plan] || 0) + 1;
  return acc;
}, {});
console.log("Por plan:", conteoPorPlan); // { premium: 2, free: 2, pro: 1 }

// 3. Emails de usuarios activos para newsletter
const emailsNewsletter = usuarios
  .filter(u => u.activo)
  .map(u => u.email);
console.log("Newsletter:", emailsNewsletter);

// 4. ¿Hay algún usuario inactivo?
console.log("Hay inactivos:", usuarios.some(u => !u.activo)); // true

// 5. ¿Todos tienen email?
console.log("Todos con email:", usuarios.every(u => u.email?.includes("@"))); // true

Errores comunes de principiantes
  1. Confundir indexOf con findIndex: indexOf busca un valor primitivo exacto; findIndex usa una función de condición.

  2. Usar === para comparar arrays: [1,2] === [1,2] es false porque compara por referencia, no por contenido. Usá JSON.stringify() o comparación elemento por elemento.

  3. Mutar arrays por accidente: sort(), reverse(), splice(), push(), pop() mutan el original. Usá spread [...arr] para copiar primero.

  4. No manejar arrays vacíos: Siempre verificá if (arr.length > 0) antes de acceder a elementos o usar reduce sin valor inicial.

  5. Confundir slice con splice: slice no muta y retorna una porción; splice muta y agrega/quita elementos.


Puntos clave de esta lección
  1. Array.from() es la forma más versátil de crear arrays desde otros iterables.
  2. Conocé la diferencia entre métodos mutables (push, pop, sort) e inmutables (map, filter, slice).
  3. at(-1) accede al último elemento de forma limpia (en vez de arr[arr.length-1]).
  4. ES2023 trajo versiones inmutables: toSorted(), toReversed(), toSpliced().
  5. Set es la forma más elegante de eliminar duplicados: [...new Set(arr)].
  6. Spread [...arr] crea una copia superficial — úsalo antes de mutar.
  7. Los arrays son la estructura de datos más común en APIs — dominar sus métodos es esencial.

Quiz de autoevaluación

1. ¿Qué retorna [1,2,3].at(-1)?
a) undefined
b) 1
c) 3
d) Error

2. ¿Cuál de estos métodos MUTA el array original?
a) map()
b) filter()
c) push()
d) slice()

3. ¿Cómo se eliminan duplicados de un array de la forma más simple?
a) arr.filter(unique)
b) [...new Set(arr)]
c) arr.removeDuplicates()
d) Array.unique(arr)

4. ¿Qué diferencia hay entre slice() y splice()?
a) Son lo mismo
b) slice no muta, splice sí muta el original
c) splice no muta, slice sí muta
d) Ambos mutan el original

5. ¿Cómo crearías un array del 1 al 10?
a) new Array(10)
b) Array.from({length: 10}, (_, i) => i + 1)
c) [1..10]
d) Array.range(1, 10)

Respuestas: 1-c, 2-c, 3-b, 4-b, 5-b


💡 Concepto Clave

Revisemos los puntos más importantes de esta lección antes de continuar.

Ejercicio práctico

Misión: Sistema de playlist musical

Creá un objeto playlist que use arrays internamente para gestionar canciones:

  1. agregar(cancion) — agrega una canción { titulo, artista, duracion } al final
  2. insertar(posicion, cancion) — inserta en una posición específica
  3. quitar(titulo) — quita una canción por título
  4. buscar(texto) — busca canciones que contengan el texto en título o artista
  5. ordenarPor(campo) — retorna la playlist ordenada por titulo, artista o duración
  6. duracionTotal() — retorna la duración total en minutos
  7. aleatorio() — retorna una copia desordenada aleatoriamente (shuffle)
const miPlaylist = crearPlaylist();
miPlaylist.agregar({ titulo: "Bohemian Rhapsody", artista: "Queen", duracion: 355 });
miPlaylist.agregar({ titulo: "Imagine", artista: "John Lennon", duracion: 183 });
// ... más canciones
console.log(miPlaylist.duracionTotal());
console.log(miPlaylist.buscar("queen"));
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
  • Comprendo el concepto principal y puedo explicarlo con mis palabras
  • Entiendo cómo aplicarlo en mi situación específica
  • Necesito repasar algunas partes antes de continuar
  • Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.