O JavaScript tem um operador ... incorporado que facilita o trabalho com um número indefinido de elementos. Consoante o contexto, chama-se operador rest ou operador spread.
Quando o ... aparece do lado esquerdo de uma atribuição, esses três pontos são conhecidos como o operador rest. Os três pontos, em conjunto com o nome de uma variável, formam aquilo a que se chama um elemento rest. Recolhe zero ou mais valores e guarda-os num único array.
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]
Repara que em JavaScript, ao contrário de algumas outras linguagens, um elemento rest não pode ter uma vírgula final. Tem obrigatoriamente de ser o último elemento numa atribuição por desestruturação. O exemplo abaixo lança um SyntaxError:
const [...items, last] = [2, 4, 8, 16]
Tal como acontece com os arrays, o operador rest também pode ser utilizado para recolher uma ou mais propriedades de um objeto e guardá-las num único objeto.
const { street, ...address } = {
street: 'Platz der Republik 1',
postalCode: '11011',
city: 'Berlin',
};
street;
// => 'Platz der Republik 1'
address;
// => {postalCode: '11011', city: 'Berlin'}
Quando o ... aparece na definição de uma função, ao lado do seu último argumento, esse parâmetro chama-se parâmetro rest. Permite que a função aceite um número indefinido de argumentos na forma de um array.
function concat(...strings) {
return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'
Quando o ... aparece do lado direito de uma atribuição, é conhecido como o operador spread. Expande um array numa lista de elementos. Ao contrário do elemento rest, pode aparecer em qualquer posição de uma expressão literal de array e pode haver mais do que um.
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]
Tal como acontece com os arrays, o operador spread também pode ser utilizado para copiar propriedades de um objeto para outro.
let address = {
postalCode: '11011',
city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
// postalCode: '11011',
// city: 'Berlin',
// country: 'Germany',
// }
O teu amigo Linus é maquinista e conduz comboios de mercadorias entre cidades. Apesar de ser fantástico a conduzir comboios, não é tão bom com logística ou computadores. Gostaria de contar com a tua ajuda na programação para organizar os detalhes dos comboios e corrigir erros nos dados das rotas.
Para praticar, usa o operador rest ou spread para resolver cada uma das tarefas abaixo.
O teu amigo tem registado o identificador (ID) de cada vagão, mas nunca sabe quantos vagões é que o sistema vai ter de processar em cada momento.
Seria muito mais fácil para o resto do programa de logística ter estes dados reunidos num único array.
Implementa uma função getListOfWagons que aceita um número arbitrário de IDs de vagões, que são os IDs de cada vagão.
Cada ID será um número inteiro positivo.
A função deve depois devolver os IDs recebidos num único array.
getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]
A esta altura, já estás a começar a perceber os dados e a forma como são usados no programa de logística. O sistema de IDs atribui sempre à locomotiva o ID 1, e aos restantes vagões do comboio atribui um ID escolhido aleatoriamente maior do que 1.
O teu amigo teve de ligar dois vagões novos ao comboio e esqueceu-se de atualizar o sistema!
Agora, os dois primeiros vagões do array do comboio têm de ser movidos para o fim, senão fica tudo fora de ordem.
O Linus ficaria muito grato se corrigisses os erros dele.
Implementa uma função fixListOfWagons que aceita um array com o id de cada vagão.
return de um array onde os 2 primeiros elementos são reposicionados no fim do array, para que a locomotiva possa ficar à frente.
eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4, 12, 6, 3, 13, 2, 5]
Ora, bolas. Parece que alguns vagões desapareceram.
Felizmente, o teu amigo acabou de encontrar outro array que parece conter os IDs dos vagões em falta, e gostaria que os adicionasses ao array principal de IDs dos vagões.
A única coisa de que se lembra é que os valores em falta devem ser colocados imediatamente a seguir à locomotiva designada.
Com esta nova informação, escreve uma função chamada correctListOfWagons que recebe como argumentos dois arrays com os IDs de cada vagão.
Os IDs dos vagões do segundo array devem ser adicionados ao primeiro array, imediatamente a seguir à locomotiva (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]
Agora que todos os dados dos vagões estão corretos, o teu amigo gostaria que atualizasses a informação de rotas do sistema.
A informação de rotas inicial foi construída como um object, e o teu amigo gostaria que a atualizasses com os acrescentos fornecidos.
Cada rota exige informação um pouco diferente, por isso o teu amigo preferia mesmo uma solução genérica.
Implementa uma função extendRouteInformation que aceita dois objects.
O primeiro object contém as cidades entre as quais o comboio circula.
O segundo object contém outros detalhes da rota, como a velocidade ou o comprimento do comboio.
A função deve devolver um object consolidado com toda a informação de rotas.
A variável moreRouteInformation pode conter propriedades diferentes.
route = { from: 'Berlin', to: 'Hamburg' };
moreRouteInformation = { length: '100', speed: '50' };
extendRouteInformation(route, moreRouteInformation);
// => {from: "Berlin", to: "Hamburg", length: "100", speed: "50"}
O teu amigo reparou que não precisa da hora de chegada na informação de rotas. Por isso, gostaria que separasses a hora de chegada da informação de rotas.
Implementa uma função separateTimeOfArrival que aceita um object com a informação de rotas.
A função deve devolver um array em que o primeiro elemento é a hora de chegada e o segundo é um object com a informação de rotas sem a hora de chegada.
routeInformation = {
from: 'Berlin',
to: 'Hamburg',
length: '100',
timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
Inscreve-te no Exercism para aprenderes e dominares JavaScript com 37 conceitos159 exercícios, e mentoria humana real, tudo grátis.