Cassidy Williams tem uma newsletter incrível que inclui, entre outras coisas, perguntas de entrevista. Na última edição, ela incluiu a seguinte pergunta:
Dado um array de números, some todos os valores, mas apenas se o número não repete um dígito.
Exemplo:
uniqueSum([1, 2, 3]); // 6
uniqueSum([11, 22, 33]); // 0
uniqueSum([101, 2, 3]); // 5
Ao resolver esse tipo de questão, a primeira coisa que eu faço é pensar em cada etapa individualmente. É preciso primeiro remover do array todos os números que repetem um dígito e, em seguida, somar o restante. Portanto, um .filter
seguido de um .reduce
é a combinação perfeita para o que precisamos.
function uniqueSum(array: number[]) {
return array.filter(hasNoRepeatingDigit).reduce((a, b) => a + b))
}
Agora precisamos criar uma função que possa verificar se o número tem algum dígito repetido. Meu primeiro instinto é transformar o número em um array e, em seguida, usar split
para obter um array.
String(12345).split(""); // [ '1', '2', '3', '4', '5' ]
Você pode iterar sobre esse array para verificar se algum número se repete, mas também pode verificar se todos os valores são únicos, transformando em um Set e verificando se o tamanho permanece o mesmo.
new Set(String(112).split("")).size == String(112).split("").size; // false
new Set(String(123).split("")).size == String(123).split("").size; // true
Portanto, a função pode ser escrita como:
function hasNoRepeatingDigit(number) {
const arrayOfNumber = String(number).split("");
// Observe que usamos `size` para Set e `length` para arrays
return new Set(arrayOfNumber).size == arrayOfNumber.length;
}
Você pode verificar o código completo no stackblitz abaixo, que também inclui alguns testes usando vitest: