Podem ajudar com essa lógica!?
Tenho um array com 60 posições, e a cada vez que ele é utilizado preciso passar por 6 vezes, e marcar os numeros passado na posição active como true. O problema é que a cada vez que eu passo por ele, ele reseta o array, marcando somente o ultimo numero passado como true.
Code: https://github.com/heudersena/game-mega-sena/blob/development-02062023/src/cron/CronJobGamer.ts
Podem me da uma força nessa questão?
// Código
function retornaNumerosSorteados(numbers: number) {
const numberArray = Array.from({ length: 60 }, (_, i) => ({ value: i, active: false }))
const newArray = numberArray.map(item => {
return {
...item,
active: item.value == numbers
}
})
console.log(newArray);
return newArray
}
retornaNumerosSorteados(10)
retornaNumerosSorteados(14)
Saída:
[
{ value: 0, active: false },
{ value: 1, active: false },
{ value: 2, active: false },
{ value: 3, active: false },
{ value: 4, active: false },
{ value: 5, active: false },
{ value: 6, active: false },
{ value: 7, active: false },
{ value: 8, active: false },
{ value: 9, active: false },
{ value: 10, active: false },
{ value: 11, active: false },
{ value: 12, active: false },
{ value: 13, active: false },
{ value: 14, active: true },
{ value: 15, active: false },
{ value: 16, active: false },
{ value: 17, active: false },
{ value: 18, active: false },
{ value: 19, active: false },
{ value: 20, active: false },
{ value: 21, active: false },
{ value: 22, active: false },
{ value: 23, active: false },
{ value: 24, active: false },
{ value: 25, active: false },
{ value: 26, active: false },
{ value: 27, active: false },
{ value: 28, active: false },
{ value: 29, active: false },
{ value: 30, active: false },
{ value: 31, active: false },
{ value: 32, active: false },
{ value: 33, active: false },
{ value: 34, active: false },
{ value: 35, active: false },
{ value: 36, active: false },
{ value: 37, active: false },
{ value: 38, active: false },
{ value: 39, active: false },
{ value: 40, active: false },
{ value: 41, active: false },
{ value: 42, active: false },
{ value: 43, active: false },
{ value: 44, active: false },
{ value: 45, active: false },
{ value: 46, active: false },
{ value: 47, active: false },
{ value: 48, active: false },
{ value: 49, active: false },
{ value: 50, active: false },
{ value: 51, active: false },
{ value: 52, active: false },
{ value: 53, active: false },
{ value: 54, active: false },
{ value: 55, active: false },
{ value: 56, active: false },
{ value: 57, active: false },
{ value: 58, active: false },
{ value: 59, active: false }
]
Como já disseram, o problema é que dentro da função vc está recriando o array novamente. Então o certo é criar o array fora e passá-lo como argumento da função.
Mas tem outros detalhes para se pensar. Por exemplo, map
sempre retorna um novo array, então só seria interessante criar outro array se vc precisasse preservar o original. Vc precisa manter o array original, ou só precisa do resultado final, com os números setados com active: true
?
Se não precisa preservar o array original, é desnecessário usar map
e ficar criando um novo array a cada número setado. Neste caso, a função poderia simplesmente alterar o array:
function sorteiaNumero(numberArray: {value: number, active: boolean}[], activeNumber: number) {
for (const item of numberArray) {
if (item.value === activeNumber) {
item.active = true;
break;
}
}
}
// outra forma de criar o array
let numberArray = [];
for (let i = 1; i <= 60; i++) {
numberArray.push({ value: i, active: false });
}
sorteiaNumero(numberArray, 10);
sorteiaNumero(numberArray, 14);
console.log(numberArray); // 10 e 14 setados
Vi no GitHub que vc está criando um array com os números de 1 a 60 (que é diferente do exemplo que vc colocou acima, que coloca de 0 a 59). Enfim, sugeri acima uma outra forma de criá-lo, usando um for
simples.
E como os números do array não se repetem, só preciso seguir no loop até encontrar o número. Depois, posso interromper o for
usando um break
(se os números se repetissem, aí teria que tirar o break
).
Também mudei o nome do parâmetro: em vez de numbers
, usei activeNumber
. Pode parecer um detalhe besta, mas dar nomes melhores ajuda na hora de programar. O nome numbers
está no plural, e passa a ideia - neste caso, errada - de são vários números. Mas pelo que entendi, é um só, então mudei para um nome no singular e que tenha mais a ver com o que ele representa.
Um detalhe: neste caso específico vc sabe que o array tem números de 1 a 60 em ordem. Ou seja, o número 1 está na posição 0, o número 2 está na posição 1 e assim por diante. Então a função poderia ser apenas:
function sorteiaNumero(numberArray: {value: number, active: boolean}[], activeNumber: number) {
numberArray[activeNumber - 1].active = true;
}
Mas como eu já disse, é apenas para este caso específico, e só se vc garantir que sempre vai chamar a função passando um número entre 1 e 60. Para os casos mais genéricos, um loop é o mais indicado.
Complementando, dei uma olhada rápida pelo código do GitHub, e talvez essa complicação toda seja desnecessária. Nem tudo precisa de async
/await
. Por exemplo, sua função generateUniqueNumbers
, não faz o menor sentido ela retornar uma Promise
, já que não faz nenhuma operação assíncrona que necessita de espera. Bastaria que ela retornasse o array diretamente:
function generateUniqueNumbers(): Number[] {
const numeros: Number[] = [];
for (let i = 1; i <= 60; i++) {
numeros.push(i);
}
// Embaralha os números
for (let i = numeros.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[numeros[i], numeros[j]] = [numeros[j], numeros[i]];
}
// Retorna os primeiros 5 números do array
// não precisa de variáveis intermediárias, pode retornar direto
return numeros.slice(0, 6).sort((a: number, b: number) => a - b);
}
Vi que na função FN_GET_NUMBER_GAME()
vc transforma o array em string, só para passá-lo para insertValueTableGame
. Mas depois vc transforma esta string novamente em array, usando split
. Esse trabalho todo é desnecessário.
O que eu faria: remova essa função FN_GET_NUMBER_GAME()
, e use diretamente a que gera os números. E vc converte para string somente na hora de salvar:
const NEW_NAMBER_GAME = generateUniqueNumbers(); // nada de async/await, é desnecessário
...
const GAMER = await insertValueTableGame(NEW_NAMBER_GAME.toString(), LAST_NAMBER_INSERTED_TABLE_GAME);
E claro, arrume esses nomes. NAMBER está errado (é "U" em vez de "A"), mas acho que o nome atual também não é bom, pois não passa a ideia de que é o array de números. Poderia ser UNIQUE_NUMBERS
ou algo assim. Na verdade, não sei porque adotou esse padrão de tudo em maiúsculas, mas enfim. Agora que esta variável contém o array, pode usá-la no restante do programa, no lugar de TRANSFORME_STRING_TO_ARRAY
(outro péssimo nome, aliás).
Enfim, não parei pra ver todo o código, mas não entendi porque sorteiaNumeros
precisa retornar outra função. Parece que tem várias complicações desnecessárias aí.