JavaScript tiene un operador ... integrado que facilita trabajar con un número indefinido de elementos. Según el contexto, se denomina operador rest u operador spread.
Cuando ... aparece en el lado izquierdo de una asignación, esos tres puntos se conocen como el operador rest. Los tres puntos junto con un nombre de variable se denominan elemento rest. Recoge cero o más valores y los almacena en un único array.
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]
Ten en cuenta que en JavaScript, a diferencia de algunos otros lenguajes, un elemento rest no puede llevar una coma final. Debe ser el último elemento de una asignación por desestructuración. El ejemplo siguiente lanza un SyntaxError:
const [...items, last] = [2, 4, 8, 16]
De manera similar a los arrays, el operador rest también se puede usar para recoger una o más propiedades de un objeto y almacenarlas en un único objeto.
const { street, ...address } = {
street: 'Platz der Republik 1',
postalCode: '11011',
city: 'Berlin',
};
street;
// => 'Platz der Republik 1'
address;
// => {postalCode: '11011', city: 'Berlin'}
Cuando ... aparece en la definición de una función junto a su último argumento, ese parámetro se denomina parámetro rest. Permite que la función acepte un número indefinido de argumentos como un array.
function concat(...strings) {
return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'
Cuando ... aparece en el lado derecho de una asignación, se conoce como el operador spread. Expande un array en una lista de elementos. A diferencia del elemento rest, puede aparecer en cualquier parte de una expresión literal de array, y puede haber más de uno.
const oneToFive = [1, 2, 3, 4, 5];
const oneToTen = [...oneToFive, 6, 7, 8, 9, 10];
oneToTen;
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const woow = ['A', ...oneToFive, 'B', 'C', 'D', 'E', ...oneToFive, 42];
woow;
// => ["A", 1, 2, 3, 4, 5, "B", "C", "D", "E", 1, 2, 3, 4, 5, 42]
De manera similar a los arrays, el operador spread también se puede usar para copiar propiedades de un objeto a otro.
let address = {
postalCode: '11011',
city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
// postalCode: '11011',
// city: 'Berlin',
// country: 'Germany',
// }
Tu amigo Linus es maquinista y conduce trenes de mercancías entre ciudades. Aunque se le dan de maravilla los trenes, la logística y los ordenadores no se le dan ni de lejos igual de bien. Le gustaría contar con tu ayuda como programador para organizar los detalles del tren y corregir errores en los datos de las rutas.
Para practicar, usa el operador rest o spread para resolver cada una de las tareas que aparecen a continuación.
Tu amigo ha ido llevando un registro del identificador (ID) de cada vagón, pero nunca sabe cuántos vagones tendrá que procesar el sistema en un momento dado.
Al resto del programa de logística le resultaría mucho más fácil tener estos datos empaquetados en un único array.
Implementa una función getListOfWagons que acepte un número arbitrario de ID de vagones, es decir, los ID de cada vagón.
Cada ID será un número entero positivo.
La función debe devolver los ID recibidos como un único array.
getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]
A estas alturas, ya empiezas a hacerte una idea de los datos y de cómo se usan en el programa de logística. El sistema de ID siempre asigna a la locomotora el ID 1, y al resto de los vagones del tren les asigna un ID elegido al azar mayor que 1.
Tu amigo tuvo que enganchar dos vagones nuevos al tren y se olvidó de actualizar el sistema.
Ahora hay que mover los dos primeros vagones del array del tren al final, o todo quedará descolocado.
Linus te estaría muy agradecido si corrigieras sus errores.
Implementa una función fixListOfWagons que acepte un array con el id de cada vagón.
Devuelve con return un array en el que los 2 primeros elementos se recolocan al final del array, para que la locomotora quede en la parte delantera.
eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4, 12, 6, 3, 13, 2, 5]
Vaya. Parece que algunos vagones han desaparecido.
Por suerte, tu amigo acaba de encontrar otro array que parece contener los ID de los vagones que faltaban, y le gustaría que los añadieras al array principal de ID de vagones.
Lo único que recuerda es que los valores que faltan deben colocarse justo después de la locomotora designada.
Con esta nueva información, escribe una función llamada correctListOfWagons que reciba como argumentos dos arrays que contienen los ID de cada vagón.
Los ID de los vagones del segundo array deben añadirse al primer array justo después de la locomotora (ID 1).
eachWagonsID = [1, 5, 20, 7, 4, 8];
missingWagons = [3, 17, 6, 15];
correctListOfWagons(eachWagonsID, missingWagons);
// => [1, 3, 17, 6, 15, 5, 20, 7, 4, 8]
Ahora que todos los datos de los vagones son correctos, a tu amigo le gustaría que actualizaras la información de las rutas del sistema.
La información de las rutas inicial se ha construido como un object, y a tu amigo le gustaría que la actualizaras con las incorporaciones proporcionadas.
Cada ruta requiere información un poco distinta, así que tu amigo preferiría claramente una solución genérica.
Implementa una función extendRouteInformation que acepte dos objects.
El primer object contiene entre qué ciudades se mueve la ruta del tren.
El segundo object contiene otros detalles de la ruta, como la velocidad o la longitud del tren.
La función debe devolver un object consolidado con toda la información de las rutas.
La variable moreRouteInformation puede contener propiedades distintas.
route = { from: 'Berlin', to: 'Hamburg' };
moreRouteInformation = { length: '100', speed: '50' };
extendRouteInformation(route, moreRouteInformation);
// => {from: "Berlin", to: "Hamburg", length: "100", speed: "50"}
Tu amigo se ha dado cuenta de que no necesita la hora de llegada en la información de las rutas. Por eso, a tu amigo le gustaría que separaras la hora de llegada de la información de las rutas.
Implementa una función separateTimeOfArrival que acepte un objeto con la información de las rutas.
La función debe devolver un array en el que el primer elemento sea la hora de llegada y el segundo sea un objeto con la información de las rutas sin la hora de llegada.
routeInformation = {
from: 'Berlin',
to: 'Hamburg',
length: '100',
timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
Regístrate en Exercism para aprender y dominar JavaScript con 37 conceptos159 ejercicios y mentoría humana real, todo gratis.