Hay situaciones en las que tenemos un
Para ello, existen varios métodos relacionados, entre los que se encuentran los siguientes:
Método | Descripción |
---|---|
.slice(start, end) |
Devuelve los elementos desde la posición start hasta end (excluído). |
.splice(start, size) |
Altera el array, eliminando size elementos desde posición start . Muta |
.splice(start, size, e1, e2...) |
Idem. Además inserta e1 , e2 ... en la posición start . Muta |
.copyWithin(pos, start, end) |
Altera el array, modificando en pos y copiando los ítems desde start a end . Muta |
.fill(element, start, end) |
Altera los elementos del start hasta end . Muta |
Vamos a ir explicándolos uno por uno.
El método .slice()
devuelve los elementos del array desde la posición start
hasta la posición end
, permitiendo crear un nuevo array más pequeño con ese grupo de elementos. Recuerda que las posiciones empiezan a contar desde 0
. En el caso de que no se proporcione el parámetro end
, se devuelven todos los elementos desde la posición start
hasta el final del array.
const letters = ["a", "b", "c", "d", "e"];
letters.slice(3); // ["d", "e"]
letters.slice(0, 2); // ["a", "b"]
letters.slice(4, 5); // ["e"]
letters.slice(2, 5); // ["c", "d", "e"]
letters.slice(-2); // ["d", "e"]
Observa que en el primer caso, al indicar un sólo parámetro, end
es la posición del último elemento del array. En el último caso, al indicar un parámetro negativo, se empieza a contar desde el final. Recuerda que en todo momento, el letters
no sufre modificaciones.
Por otro lado, el método .splice()
realiza algo parecido a .slice()
pero con una gran diferencia: modifica el array original. Además, en el método .splice()
el segundo parámetro size
no es la posición final del subarray (como en el caso anterior), sino el tamaño del array final, es decir, el número de elementos que se van a obtener desde la posición start
.
const letters = ["a", "b", "c", "d", "e"];
letters.splice(0, 2); // Devuelve ["a", "b"]
letters // ["c", "d", "e"]
const letters = ["a", "b", "c", "d", "e"];
letters.splice(2, 1); // Devuelve ["c"]
letters // ["a", "b", "d", "e"]
Es decir, con el método .splice()
devolvemos un start
hasta la posición start + size
. Por otro lado, el array original muta y se eliminan dichos elementos.
Es posible también indicar una serie de parámetros opcionales después de los mencionados, que permitirán además de la extracción de elementos, insertar dichos elementos justo donde hicimos la extracción.
Veamos un ejemplo ilustrativo para entender bien la diferencia entre ambos:
const letters = ["a", "b", "c", "d", "e"];
// .slice() no modifica el array
letters.slice(2, 4); // Devuelve ['c', 'd']. El array no se modifica.
// .splice() si modifica el array
letters.splice(2, 2); // Devuelve ['c', 'd']. Ahora array = ['a', 'b', 'e']
letters.splice(1, 0, "z", "x"); // Devuelve []. Ahora array = ['a', 'z', 'x', 'b', 'e']
Observa que en el último caso de .splice()
, además de extraer elementos, se insertan nuevos elementos. A raíz de este último ejemplo, mencionar que también podemos insertar elementos en una posición concreta del array de dos formas alternativas:
.slice()
y .concat()
(no se muta el array original).splice()
y desestructuración (se muta el array original)Veamos un ejemplo de cada forma, primero, utilizando .slice()
y .concat()
:
const numbers = [1, 2, 3, 8, 9, 10];
const middlePart = [4, 5, 6, 7];
const firstPart = numbers.slice(0, 3); // [1, 2, 3]
const lastPart = numbers.slice(3, 6); // [8, 9, 10]
firstPart.concat(middlePart, lastPart); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers // [1, 2, 3, 8, 9, 10] (numbers no ha mutado)
Ahora, otro ejemplo, utilizando .splice()
y desestructuración. Ten en cuenta que el resultado en esta ocasión lo tendremos en la constante numbers
:
const numbers = [1, 2, 3, 8, 9, 10];
const middlePart = [4, 5, 6, 7];
numbers.splice(3, 0, ...middlePart); // [] (Elementos eliminados, en este caso, ninguno)
numbers // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (numbers ha mutado)
Como se puede ver, se ha hecho la misma operación de dos formas diferentes.
Es posible tener un array al que queremos hacer ciertas modificaciones donde .slice()
y .splice()
se quedan cortos (o no resultan cómodos). Veamos algunos métodos introducidos en ECMAScript
El primero de ellos, copyWithin(pos, start, end)
nos permite alterar el array, de modo que, empezando en la posición pos
, copiará los elementos que están desde la posición start
hasta la posición end
. El parámetro end
es opcional, de modo que si no se indica, se asume que end
es el tamaño del array.
Veamos algunos ejemplos que alteran sucesivamente el array letters
:
const letters = ["a", "b", "c", "d", "e", "f"];
// Estos métodos modifican el array original
letters.copyWithin(3, 0, 3); // ["a", "b", "c", "a", "b", "c"]
letters.copyWithin(3, 1); // ["a", "b", "c", "b", "c", "a"]
letters.copyWithin(4, 0, 1); // ["a", "b", "c", "b", "a", "a"]
Ten en cuenta que en el ejemplo anterior, la constante
letters
se va alterando en cada ejecución del método.copyWithin()
, ya que no sólo devuelve el array, sino que muta el original. UtilizastructuredClone()
si necesitas crear un nuevo array sin mutar el original.
También, en ciertos casos, nos podría interesar reducir el tamaño de un array para quedarnos con sus primeros elementos y descartar el resto. Hay una forma muy sencilla y rápida que es modificar directamente el tamaño del array mediante la propiedad .length
. Por ejemplo, hacer un numbers.length = 4
en un array de 8 elementos, reducirá el array a los primeros 4 elementos.
// Mediante slice()
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
const newNumbers = numbers.slice(0, 4);
newNumbers // [1, 2, 3, 4], numbers no cambia
// Mediante .length
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
numbers.length = 4;
numbers // [1, 2, 3, 4], numbers cambia
No crea un nuevo array, sino que reduce el tamaño del actual y descarta el resto de elementos.
Existe un método que nos permite rellenar el start
y end
para establecer la posición de inicio y/o fin donde queremos rellenar, y así sólo alterar un fragmento del array.
Ten en cuenta que con .fill()
estamos alterando el
Veamos algunos ejemplos:
const letters = ["a", "b", "c", "d", "e", "f"];
// Estos métodos modifican el array original
letters.fill("Z", 0, 5); // ["Z", "Z", "Z", "Z", "Z", "f"]
letters.fill("AA", 0, 2); // ["AA", "AA", "Z", "Z", "Z", "f"]
letters.fill(1); // [1, 1, 1, 1, 1]
new Array(5).fill(5); // [5, 5, 5, 5, 5]
Observa que en el último caso, con new Array(5)
creamos un array de 5 elementos undefined y lo rellenamos con números 5
con el método .fill()
.
También podríamos utilizar un enfoque más funcional y hacer algo similar con el método .map()
, uno de los métodos que tienen los
const elements = [1, 2, undefined, undefined, 5];
elements.fill(10); // [10, 10, 10, 10, 10]
elements.map(element => 10); // Equivalente al anterior, sin mutar el original
const elements = [1, 2, undefined, undefined, 5];
elements.fill(10, 2, 4); // [1, 2, 10, 10, 5]
elements.map(element => !element ? 10 : element); // Equivalente al anterior, sin mutar el original
Si te interesa este enfoque, hablamos sobre ello más adelante, en el tema Array functions.