O JavaScript tem um operador ... embutido que facilita trabalhar com um número indefinido de elementos. Dependendo do contexto, ele é chamado de operador rest ou operador spread.
Quando ... aparece do lado esquerdo de uma atribuição, esses três pontos são conhecidos como o operador rest. Os três pontos junto com um nome de variável formam o que chamamos de elemento rest. Ele coleta zero ou mais valores e os armazena em um único array.
const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]
Repare que no JavaScript, diferente de algumas outras linguagens, um elemento rest não pode ter vírgula final. Ele precisa ser o último elemento de uma atribuição por desestruturação. O exemplo abaixo lança um SyntaxError:
const [...items, last] = [2, 4, 8, 16]
Assim como acontece com os arrays, o operador rest também pode ser usado para coletar uma ou mais propriedades de um objeto e armazená-las em um ú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 ... aparece na definição de uma função ao lado do último argumento dela, esse parâmetro é chamado de parâmetro rest. Ele permite que a função aceite um número indefinido de argumentos como um array.
function concat(...strings) {
return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'
Quando ... aparece do lado direito de uma atribuição, ele é conhecido como o operador spread. Ele expande um array em uma lista de elementos. Diferente do elemento rest, ele pode aparecer em qualquer posição de uma expressão literal de array, e pode haver mais de 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]
Assim como acontece com os arrays, o operador spread também pode ser usado para copiar propriedades de um objeto para outro.
let address = {
postalCode: '11011',
city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
// postalCode: '11011',
// city: 'Berlin',
// country: 'Germany',
// }
Seu amigo Linus é maquinista e dirige trens de carga entre cidades. Embora ele seja incrível com trens, não é tão bom assim com logística ou computadores. Ele gostaria de contar com a sua ajuda na programação para organizar os detalhes dos trens e corrigir erros nos dados de rota.
Para praticar, use o operador rest ou spread para resolver cada uma das tarefas abaixo.
Seu amigo vem anotando o identificador (ID) de cada vagão, mas nunca tem certeza de quantos vagões o sistema vai precisar processar em um determinado momento.
Seria muito mais fácil para o resto do programa de logística ter esses dados empacotados em um único array.
Implemente 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 então retornar os IDs recebidos como um único array.
getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]
A essa altura, você já está começando a entender os dados e como eles são usados no programa de logística. O sistema de IDs sempre atribui à locomotiva o ID 1, e o restante dos vagões do trem recebe um ID escolhido aleatoriamente, maior que 1.
Seu amigo precisou conectar dois vagões novos ao trem e esqueceu de atualizar o sistema!
Agora, os dois primeiros vagões do array do trem precisam ir para o final, senão tudo vai ficar fora de ordem.
Linus ficaria muito grato se você corrigisse os erros dele.
Implemente uma função fixListOfWagons que aceita um array com o id de cada vagão.
Ela return um array em que os 2 primeiros elementos são reposicionados para o final do array, para que a locomotiva fique na frente.
eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4, 12, 6, 3, 13, 2, 5]
Opa. Parece que alguns vagões sumiram.
Felizmente, seu amigo acabou de encontrar outro array que parece conter os IDs dos vagões que faltavam, e gostaria que você os adicionasse ao array principal de IDs de vagões.
Tudo o que ele lembra é que os valores que faltam devem ser colocados logo depois da locomotiva designada.
Com essa nova informação, escreva 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, logo depois da 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, seu amigo gostaria que você atualizasse as informações de rota do sistema.
As informações de rota iniciais foram construídas como um object, e seu amigo gostaria que você as atualizasse com as adições fornecidas.
Cada rota exige informações um pouco diferentes, então seu amigo preferiria bastante uma solução genérica.
Implemente uma função extendRouteInformation que aceita dois objects.
O primeiro object contém entre quais cidades a rota do trem passa.
O segundo object contém outros detalhes da rota, como a velocidade ou o comprimento do trem.
A função deve retornar um object consolidado com todas as informações de rota.
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"}
Seu amigo percebeu que não precisa do horário de chegada nas informações de rota. Por isso, seu amigo gostaria que você separasse o horário de chegada das informações de rota.
Implemente uma função separateTimeOfArrival que aceita um objeto com as informações de rota.
A função deve retornar um array em que o primeiro elemento é o horário de chegada e o segundo é um objeto com as informações de rota sem o horário de chegada.
routeInformation = {
from: 'Berlin',
to: 'Hamburg',
length: '100',
timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
Crie sua conta no Exercism para aprender e dominar JavaScript com 37 conceitos159 exercícios e mentoria humana de verdade, tudo de graça.