Arrays: push, splice y sort
En resumen: Un array en JavaScript también es una lista: push añade al final, splice quita elementos sin dejar huecos, y sort lo ordena, pero los números como texto si no le das una función.
Problema
El carrito está lleno
Estás escribiendo el carrito de compras de una tienda en línea, y guardas los productos en un array, como en la lección sobre arrays: cada producto en su propio índice. JavaScript te deja escribir también más allá del final, pero tienes que llevar la cuenta del primer índice libre. Y cuando el cliente quita un producto, queda un hueco:
const cart = ["Pan", "Leche", "Café"];
// Un cuarto producto: escribimos en el primer índice libre.cart[cart.length] = "Mantequilla";
// El cliente quita la leche.cart[1] = undefined;
for (const item of cart) { console.log(item);}console.log(cart.length);PanundefinedCaféMantequilla4undefined. Y el número de productos ya no es cart.length: eso es 4, pero hay 3 productos.Es mucho código para algo que toda tienda hace todo el tiempo.
La idea
push y splice: el array se cuida solo
El array tiene métodos que hacen esto por ti. Copia y desplaza solo. Una colección que crece y se encoge así se llama lista, y en JavaScript es el propio array:
const cart = [];cart.push("Pan");cart.push("Leche");cart.push("Café");cart.push("Mantequilla");cart.splice(cart.indexOf("Leche"), 1);console.log(cart);console.log(`Productos: ${cart.length}`);[ 'Pan', 'Café', 'Mantequilla' ]Productos: 3pushañade al final.- No hay un método que quite por valor.
indexOfencuentra el índice de «Leche», ysplice(index, 1)quita un elemento desde ahí y cierra el hueco: «Café» pasa al lugar de «Leche». lengthes cuántos elementos hay ahora mismo.console.logimprime todo el array entre corchetes, con el texto entre comillas.
Esto es lo que hace el array por dentro. Tú no eliges cuántos lugares tiene. Lo decide el motor que ejecuta el código (V8 en Node y en Chrome). Un array de 3 productos escrito en el código tiene exactamente 3 lugares, así que se llena con el cuarto:
const cart = ["Pan", "Leche", "Café"];cart.push("Mantequilla");cart.splice(cart.indexOf("Leche"), 1);console.log(cart);console.log(`Productos: ${cart.length}`);Paso a paso, en palabras
- cart apunta a un array. Por dentro tiene length y un array aparte, elements, con 3 lugares.
- Los productos del código llenan los lugares uno a uno. El array está lleno: 3 de 3.
- No hay sitio. push crea un array con 22 lugares y copia en él los elementos.
- Ahora elements apunta al array nuevo, y el viejo ya no lo necesita nadie. «Mantequilla» va al lugar libre.
- splice quita «Leche», y todo lo que viene después se mueve un lugar a la izquierda. No queda ningún hueco.
- Desde fuera solo ves un array de tres productos. El motor V8 decide cuántos lugares tiene por dentro: el lenguaje no lo promete.
Más precisamente, para curiosos
- También existe
delete cart[1], pero no desplaza nada. Deja un hueco, ylengthsigue igual:
const cart = ["Pan", "Leche", "Café"];delete cart[1];console.log(cart, cart.length);[ 'Pan', <1 empty item>, 'Café' ] 3Para un array, usa splice.
La idea
Qué va en un array
Un array no pregunta qué pones en él. Un texto y un número pueden estar uno al lado del otro:
const cart = [];cart.push("Pan");cart.push(5);console.log(cart);[ 'Pan', 5 ]Parece práctico, pero el error aparece más tarde, donde esperas texto. Por eso un array guarda un solo tipo de cosa: solo productos, solo precios.
JavaScript por sí mismo no tiene forma de decir «un array solo de texto». Eso lo hace TypeScript. Es JavaScript con tipos: allí un array de texto es string[], y cart.push(5) es un error directamente en el editor.
La idea
Índices: [i], splice, indexOf, includes
Un array tiene índices del 0 a tasks.length - 1. Lees y reemplazas con [ ], e insertas con splice:
const tasks = ["Factura de marzo", "Llamar al banco", "Informe del almacén"];
console.log(tasks[0]);tasks[1] = "Reunión en el banco";tasks.splice(0, 0, "Café con el equipo");console.log(tasks.join(", "));console.log(tasks.indexOf("Informe del almacén"));console.log(tasks.includes("Llamar al banco"));Factura de marzoCafé con el equipo, Factura de marzo, Reunión en el banco, Informe del almacén3falsetasks[i]lee, ytasks[i] = xreemplaza.splice(i, 0, x)inserta en el índiceiy desplaza el resto a la derecha. El cero significa «no quitar nada».indexOf(x)busca y devuelve el índice o-1, eincludes(x)solo dice si está.join(", ")une los elementos en un solo texto, separados por comas.
Más precisamente, para curiosos
- Un índice fuera del array no detiene el programa. Da
undefined.at(-1)cuenta desde atrás y da el último elemento:
const tasks = ["Factura de marzo", "Llamar al banco", "Informe del almacén"];console.log(tasks[3]);console.log(tasks.at(-1));console.log(tasks.indexOf("Nóminas"));undefinedInforme del almacén-1includeseindexOfcomparan con===. El texto es un valor, así que encuentran un texto igual.- Insertar y quitar al principio es lento en un array grande: cada elemento después del índice se mueve un lugar. Con un millón de elementos, son un millón de movimientos.
Pruébalo
¿Quién sigue?
La lista de pacientes que esperan en el médico. Juan entra, y Ana tiene cita, así que ocupa el segundo lugar.
¿Qué imprimirá el programa?
const waiting = ["Juan", "María", "Pedro"];waiting.shift();waiting.splice(1, 0, "Ana");console.log(waiting, waiting.length);shift() quita a Juan, y María pasa a ser la primera, en el índice 0. splice(1, 0, "Ana") inserta a Ana en el índice 1 y empuja a Pedro a la derecha. Quedan tres.
shift() quita el primer elemento, como splice(0, 1).
La idea
Recorrer los elementos
Recorres un array con for...of cuando solo necesitas los elementos, o con un índice cuando también necesitas el número:
const cart = ["Pan", "Café", "Mantequilla"];
for (const item of cart) { console.log(`- ${item}`);}for (let i = 0; i < cart.length; i++) { console.log(`${i + 1}. ${cart[i]}`);}- Pan- Café- Mantequilla1. Pan2. Café3. MantequillaMás precisamente, para curiosos
- No quites elementos de un array mientras lo recorres con
for...of. El programa no se detiene, pero se salta elementos:
const cart = ["Pan", "Pan", "Leche"];for (const item of cart) { if (item === "Pan") { cart.splice(cart.indexOf(item), 1); }}console.log(cart);[ 'Pan', 'Leche' ]El segundo «Pan» se quedó. splice desplazó todo a la izquierda, y el bucle siguió desde el índice siguiente y nunca lo vio. No hay error, así que un fallo así es difícil de detectar.
- Si tienes que quitar, recorre con un índice de atrás hacia delante. Así, quitar no desplaza los elementos que todavía no has comprobado:
const cart = ["Pan", "Pan", "Leche"];for (let i = cart.length - 1; i >= 0; i--) { if (cart[i] === "Pan") { cart.splice(i, 1); }}console.log(cart);[ 'Leche' ]filter.La idea
Números en un array
Un array de puntuaciones es como un array de texto. El número está en el array tal cual:
const scores = [85, 64, 91];
let total = 0;for (const score of scores) { total += score;}console.log(`Media: ${total / scores.length}`);Media: 80JavaScript imprime 80, no 80.0: para él los números enteros y los decimales son el mismo tipo, number.
Más precisamente, para curiosos
- Un número en JavaScript es un valor primitivo, no un objeto. Por eso
===compara los valores, y dos números iguales son iguales. También existe un envoltorio,new Number(257), que crea un objeto, y dos objetos son distintos aunque guarden lo mismo:
const c = Number("257");const d = Number("257");console.log(c === d);console.log(new Number(257) === new Number(257));truefalseNo necesitas new Number. Escribe los números directamente.
Pruébalo
Encuentra el error
Un teatro guarda los asientos ocupados en un array. Un cliente deja el asiento 2, y el programa debería imprimir [ 12, 7, 5 ]. En cambio imprime [ 12, 2, 5 ]. ¿Qué línea tiene el error?
Elige la línea con el error.
splice(2, 1) quita un elemento desde el índice 2, que es el asiento 7. Para quitar el valor 2, primero encuentra su índice: seats.splice(seats.indexOf(2), 1). Cuidado si el valor no está: indexOf da -1, y splice(-1, 1) quita el último elemento. Así que comprueba primero con includes.Más precisamente, para curiosos
const seats = [12, 7, 5];seats.splice(seats.indexOf(2), 1);console.log(seats);[ 12, 7 ]La idea
Ordenar y un array que no cambia
sort() ordena el array en el sitio. El texto sale en orden alfabético. Pero los números no salen por tamaño:
const cities = ["Sevilla", "Madrid", "Valencia"];cities.sort();console.log(cities);
const prices = [30, 5, 12];prices.sort();console.log(prices);prices.sort(function (a, b) { return a - b;});console.log(prices);[ 'Madrid', 'Sevilla', 'Valencia' ][ 12, 30, 5 ][ 5, 12, 30 ]Sin una regla, sort convierte todo en texto y compara el texto. «12» va antes que «30», y «30» antes que «5», como en un diccionario. Así que a los números les das una regla: una función que recibe dos números y devuelve a - b. Un resultado negativo significa «a va antes que b». Por ahora, cópiala. En la lección «Clases anidadas» verás cómo escribir reglas así.
Un array que no cambia se crea con Object.freeze. Es inmutable: no puedes añadir, quitar ni ordenar en él.
const days = Object.freeze(["lun", "mar", "mié"]);days.push("jue");TypeError: Cannot add property 3, object is not extensibleconst no basta para esto: solo impide que days apunte a otro array, mientras que el propio array todavía puede cambiar.
Más precisamente, para curiosos
- El texto se ordena por los códigos de sus caracteres. Las mayúsculas van antes que las minúsculas, así que «Pera» va antes que «manzana»:
const fruit = ["manzana", "Pera", "banana", "Uva"];fruit.sort();console.log(fruit);[ 'Pera', 'Uva', 'banana', 'manzana' ]toSorted()devuelve un array nuevo, ordenado, y no toca el viejo:
const prices = [30, 5, 12];const cheapFirst = prices.toSorted(function (a, b) { return a - b;});console.log(cheapFirst, prices);[ 5, 12, 30 ] [ 30, 5, 12 ]- Cómo ordenar tus propios objetos, por ejemplo productos por precio, lo verás en la lección «Clases anidadas».
Ejercicio
Arrays en clases
#books), y el código debajo de las clases solo llama a sus métodos.1. Una estantería. Una clase BookShelf con un método addBook(title) que pone el libro al final, y takeBook(), que devuelve y quita el primer libro (o null si la estantería está vacía). Añade count() y toString(). Añade «Bajo el yugo», «Tabaco» y «El candelabro de hierro», toma un libro e imprime el resto.
Tomado: Bajo el yugo2 quedan: [Tabaco, El candelabro de hierro]2. Un registro de eventos. Una clase Event con una fecha y una descripción, y una clase EventLog con los métodos addEvent(date, description) y getEventsBetween(from, to), que devuelve un array con los eventos entre las dos fechas, incluidas. Las fechas son texto con la forma 2026-03-31. Con esta forma, el texto se ordena igual que las fechas, así que <= y >= las comparan correctamente. Añade cuatro eventos: 2026-01-15 «Inventario anual», 2026-03-31 «Informe del primer trimestre», 2026-05-20 «Nuevo proveedor de café», 2026-09-01 «Nuevo curso escolar». Imprime los del 2026-03-01 al 2026-06-30.
2026-03-31 Informe del primer trimestre2026-05-20 Nuevo proveedor de café3. Un cuaderno. Una clase Note con un título y un contenido, y una clase Notebook con los métodos addNote, findNote(title) (devuelve la nota o null), deleteNote(title) (devuelve true si borró algo) y count(). Añade las notas «POO», «Colecciones» y «SQL», busca «Colecciones», borra «POO» y comprueba que ya no está.
Colecciones: el array crece soloBorrada: POONotas: 2No hay ninguna nota de POO.4. Cálculo mental. Una clase Question con un texto y la respuesta correcta, y una clase MathGame con un array de preguntas, un método addQuestion y un método start(). start hace las preguntas una a una, lee la respuesta y al final dice cuántas fueron correctas. Las preguntas son 2 + 2, 3 * 4 y 15 - 9.
start lee con ask de la lección sobre la entrada, así que es async start(), y la llamada es await game.start(). Un método que espera la entrada se escribe así. Por ahora, cópialo.
41272 + 2 = ¡Correcto!3 * 4 = ¡Correcto!15 - 9 = Incorrecto, la respuesta es 6.Puntuación: 2 de 3Más tareas
- Sin repetidos. Lee 6 nombres y reúnelos en un array, saltándote los que ya están. Para la entrada Juan, María, Juan, Ana, María, Pedro la salida es
[ 'Juan', 'María', 'Ana', 'Pedro' ]. - El producto más caro. Un array guarda precios. Encuentra el más alto y su índice, sin
Math.max. - La lista al revés. Escribe una función que devuelva un array nuevo con los mismos elementos en orden inverso. No cambies el original.
- Una lista de la compra. Lee las órdenes
add milk,remove milk,listyend, y guarda la lista entre ellas. La orden de quitar un producto que no está dice «No existe ese producto.».
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Polimorfismo · Interfaces sin interface · Excepciones · Cadenas
- Continúa en: Pila, cola y lista enlazada · Map y Set · Códigos hash y funciones hash · Clases anidadas y datos
- Ejercicios sobre el tema: Colecciones