O ponto chave aqui é manipulação da string recebida em partes, visto que ela sempre seguirá o mesmo padrão. Com isso fica fácil ver como podemos alterar o array a partir dela. Outra coisa que podemos fazer é utilizar classes, apesar de não ser obrigatório.
Como estamos utilizando classes, podemos utilizar a lista de corredores como um atributo, visto que ela será utilizada internamente nos métodos. Outra coisa que já podemos adicionar é o método de obter a classificação. Isso será bem simples por já termos um array, tudo que precisamos fazer é criar um objeto e adicionar todos os elementos utilizando a posição mais 1, já que um array começa por 0 mas uma classificação começar por 1.
class Race { constructor(...racers) {
this.racers = racers
}
getClassification() {
const classification = {}
for (let i = 0; i < this.racers.length; i++) {
classification[i + 1] = this.racers[i];
}
return classification
}
}
Agora podemos adicionar um método para lidar com a atualização da classificação. Ele pode obter tanto o nome do corredor quanto a ação a ser executada a partir da desestruturação de um array convertido da string recebida, pois ela sempre virá no forma nome + espaço + ação. Se a ação for de eliminar chamamos o método próprio, senão chamamos o método de atualizar a classificação para mais ou menos.
class Race {
constructor(...racers) {
this.racers = racers
}
getClassification() {
const classification = {}
for (let i = 0; i < this.racers.length; i++) {
classification[i + 1] = this.racers[i];
}
return classification
}
updateClassification(str) {
const [racer, action] = str.split(' ')
if (action.includes('ELIMINATE')) {
this.eliminateRacer(racer)
} else {
this.updateRacer(racer, action)
}
}
}
Agora vamos adicionar os métodos que faltam. Primeiro, para atualizar a classificação de um corredor subindo ou descendo posições podemos dividir o array dos corredores entre os ativos e os eliminados, pois os corredores ativos não podem se misturar com os eliminados na classificação. Depois pegamos a posição atual do corredor que estamos manipulando com o método .indexOf() e atualizamos ela utilizando o número da ação passada multiplicado por -1, porque em um array temos que reduzir a posição na classificação ao aumentar o índice. Também podemos aproveitar para inserir uma validação na posição que está sendo atualizada, de forma que ela não esteja fora da lista. Agora só resta remover o corredor do array atual e inseri-lo na posição atualizada.
class Race {
constructor(...racers) {
this.racers = racers
}
getClassification() {
const classification = {}
for (let i = 0; i < this.racers.length; i++) {
classification[i + 1] = this.racers[i];
}
return classification
}
updateClassification(str) {
const [racer, action] = str.split(' ')
if (action.includes('ELIMINATE')) {
this.eliminateRacer(racer)
} else {
this.updateRacer(racer, action)
}
}
updateRacer(racer, action) {
const eleminated = this.racers.filter(racer => racer.includes('ELIMINATED'))
const active = this.racers.filter(racer => !racer.includes('ELIMINATED'))
const currentPosition = active.indexOf(racer)
const updatedPosition = currentPosition + Number(action) * -1
if (updatedPosition >= this.racers.length || updatedPosition < 0) {
console.log('Erro! Atualização inválida.')
return
}
active.splice(currentPosition, 1)
this.racers = [...active.slice(0, updatedPosition), racer, ...active.slice(updatedPosition), ...eleminated]
}
}
Por fim, o método para eliminar um corredor é mais simples. Tudo que precisamos fazer é separar os corredores novamente em ativos e eliminados, remover o corredor da lista dos ativos e adicioná-lo a lista dos eliminados.
class Race {
constructor(...racers) {
this.racers = racers
}
getClassification() {
const classification = {}
for (let i = 0; i < this.racers.length; i++) {
classification[i + 1] = this.racers[i];
}
return classification
}
updateClassification(str) {
const [racer, action] = str.split(' ')
if (action.includes('ELIMINATE')) {
this.eliminateRacer(racer)
} else {
this.updateRacer(racer, action)
}
}
updateRacer(racer, action) {
const eleminated = this.racers.filter(racer => racer.includes('ELIMINATED'))
const active = this.racers.filter(racer => !racer.includes('ELIMINATED'))
const currentPosition = active.indexOf(racer)
const updatedPosition = currentPosition + Number(action) * -1
if (updatedPosition >= this.racers.length || updatedPosition < 0) {
console.log('Erro! Atualização inválida.')
return
}
active.splice(currentPosition, 1)
this.racers = [...active.slice(0, updatedPosition), racer, ...active.slice(updatedPosition), ...eleminated]
}
eliminateRacer(racer) {
const eleminated = this.racers.filter(racer => racer.includes('ELIMINATED'))
const active = this.racers.filter(racer => !racer.includes('ELIMINATED'))
active.splice(active.indexOf(racer), 1)
this.racers = [...active, `${racer} ELIMINATED`, ...eleminated]
}
}