Adicionar novos elementos em um array
12/03/2020
0
Estou tentando adicionar novos elementos em um array.
Entretanto, se o elemento a ser adicionado no array já existir, gostaria que a função procurasse outro elemento para adicionar, e que a mesma só fosse encerrada após conseguir adicionar um elemento novo.
Eu tenho dois objetos:
const allMaps = { Stage0: null, Stage1: [5,6,7,8,9], Stage2: [11,12,13,14,15], Stage3: [17,18,19,20,21], Stage4: [23,24,25,26,27], Stage5: [29,30,31,32,33], Stage6: [35,36,37,38,39] } let playedMaps = { Stage0: null, Stage1: [], Stage2: [], Stage3: [], Stage4: [], Stage5: [], Stage6: [] }
Na função "addPlayedMaps(stage)" a seguir, eu quero adicionar um único valor de allMaps.Stage1 para o playedMaps.Stage1.
function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max + 1); return Math.floor(Math.random() * (max - min)) + min; }; function addPlayedMaps(stage){ for(let i = getRandomInt(5, 9); playedMaps[stage].indexOf(i) === -1; i = getRandomInt(5, 9) ){ playedMaps[stage].push(i); } return playedMaps; }; addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); console.log(playedMaps["Stage1"].sort());
Então eu executo a função 5 vezes, para que todos os valores de allMaps.Stage1 preencham o playedMaps.Stage1.
addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); addPlayedMaps("Stage1"); console.log(playedMaps["Stage1"].sort());
Entretanto, nem sempre eu consigo adicionar 5 valores. As vezes o console log me dá 4 valores ou 3...
O que tem de errado no meu loop for() ?
for(let i = getRandomInt(5, 9); // i é igual a qualquer um dos números: 5, 6, 7, 8, 9.
playedMaps[stage].indexOf(i) === -1; // Se i não existir no objeto(se o index dele for -1) playedMaps[stage], então executa a declaração.
i = getRandomInt(5, 9) ){ // Caso i já exista no objeto, fazer o sorteio de novo entre os números 5 a 9.
playedMaps[stage].push(i); // Declaração sendo executada e adicionando i ao objeto.
}
Eliaquim Nascimento
Post mais votado
12/03/2020
Um outro problema da sua função é que ela pega um intervalo de números ( motivo pelo qual eu recomendo usar um array de strings de primeira pra facilitar o entendimento )
Quando você faz getRandomInt(5, 9), isso se resolve pro Stage1, mas não resolve para o stage2, que vai de 11 a 15, obrigando você a escrever dois loops diferentes, não possibilitando você reutilizar sua função para outros stages.
Outro problema do seu loop é que ele não leva em consideração todos os estágios de allMaps, causando uma coincidência de valores.
Abaixo eu te proponho uma funcao que você pode reutilizar para qualquer stage.
Ela vai adiciona um único mapa no array toda vez que ela for chamada e vai validar se o array já está cheio também.
Dá uma olhadinha
function addPlayedMaps (stage) { const allMapsLenght = (allMaps[stage].length - 1) const randomInt = getRandomInt(0, allMapsLenght) if (playedMaps[stage].length >= allMaps[stage].length) { return } const hasPlayed = playedMaps[stage].some(mapItem => { if (mapItem === allMaps[stage][randomInt]) { return true } }) if (!hasPlayed && !!allMaps[stage][randomInt]) { playedMaps[stage].push(allMaps[stage][randomInt]) } if (hasPlayed) { addPlayedMaps(stage) } }
Stella Oliveira
Mais Posts
12/03/2020
Eliaquim Nascimento
Hmm... Não imaginaria que fosse isso... achei que reatribuir o valor ali, funcionasse como i++ ou i--, que no meu caso seria gerar um outro valor aleatório de 5 a 9.
Nesse caso, eu poderia gerar esse valor novamente no loop, dentro do corpo(declaração)?
for(let i = getRandomInt(5, 9); playedMaps[stage].indexOf(i) === -1; ){ playedMaps[stage].push(i); i = getRandomInt(5, 9) // Aqui? }
Array de strings de primeira?
Tipo assim:
ler arr = [ ["5","6","7","8","9"], ["11","12","13","14","15"] ... ]
Sim, verdade! É que eu tava querendo primeiro fazer funcionar hahaha
Eu testei a função e funcionou direitinho!!! Ficou fera, obrigadão mesmo!
playedMaps[stage].push(allMaps[stage][randomInt])
}
Usar o "randomInt aqui > allMaps[stage][randomInt] < foi um mindblowing pra mim xD
Valeu mesmo.
Eu só não entendi essa condição: "!!allMaps[stage][randomInt]", dois pontos de exclamação? Duas negativas? Para que serve esses dois?
13/03/2020
Stella Oliveira
No javascript:
//Se você fizer const obj = { foo: "bar" } if (obj.foo) // isso é true por que o JS avalia ele como um objeto que existe if (!obj.foo) // isso é false por que o javascript converte para booleano if (!!obj.foo) // eu estou convertendo para um booleano e invertendo o valor dele !obj.foo == false, !!obj.foo == true
É só pra garantir que vai funcionar
Entretanto, o seu código ainda tem um problema. Se um dos seus arrays contiver um número 0, ele vai dar errado. Por que em JS, o valor 0 é tratado como false. Sei que sua questão tem a ver com aprender, mas vale atentar que:
const allMaps = { Stage0: null, Stage1: [0, 5,6,7,8,9] // esse 0 vai automaticamente dar false }
13/03/2020
Eliaquim Nascimento
Entendi o lance do "!!".
Sim, eu fiquei ciente que o número 0 pode dar false, depois de entender a explicação.
Esses números são o ID de cada mapa, e os Id's são sempre maiores que 0, então não corro esse risco.
Muito obrigado pela ajuda, problema resolvido! ^^
14/03/2020
Stella Oliveira
Você citou
Array de strings de primeira?
Tipo assim:
ler arr = [ ["5","6","7","8","9"], ["11","12","13","14","15"] ... ]
Eu queria dizer strings mesmo. Acho que nesse ponto você já sabe, mas vale lembrar que o JS é uma linguagem que força tipagem
if (5 == "5") // isso é true
Então usar números em comparações exatas sempre é meio perigoso. Eu, particularmente, usaria assim ( já aviso que entendo o problema de dar nomes assim, uma hora a criatividade acaba haha ):
let arr = ["dust2", "poolday"] // e por ai vai
Mas eu digo isso mais pelo contexto. Na hora de programar, é mais fácil eu pensar que eu to comparando a "dust2" dos que já joguei com a "dust2" de allMaps. Eu falei isso mais por facilitar seu entendimento do seu código, mas depois que você me disse que recebe um array de ids, eu meio que entendi qual foi a intenção :)
Você também mencionou
Você até poderia fazer o que você propôs ( não sei dizer se daria certo por que eu mesmo não testei ), mas eu te colocaria o seguinte argumento:
Escrever o código daquela maneira não é muito comum, portanto deixa seu código mais difícil de entender pra um futuro colega e até mesmo pra você daqui um tempo. Eu, inclusive, te faço uma proposta: volta nessa questão que você abriu daqui 3 meses e dá uma lida nela. Eu te garanto que vai ser meio difícil de você entender o código que você propôs, por que nele falta clareza de intenção. Algo que é bastante discutido no livro Clean Code do Martin Fowler ( super recomendo, inclusive )
:D
14/03/2020
Stella Oliveira
- https://www.amazon.com.br/C%C3%B3digo-limpo-Robert-C-Martin/dp/8576082675/ref=asc_df_8576082675/?tag=googleshopp00-20&linkCode=df0&hvadid=379792215563&hvpos=&hvnetw=g&hvrand=4226168958323978339&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1001566&hvtargid=pla-398225630878&psc=1
- https://martinfowler.com/ieeeSoftware/explicit.pdf
- https://medium.com/@kennethreilly/coding-with-intention-d1d61f5add20
- https://novatec.com.br/livros/programador-melhor/
14/03/2020
Eliaquim Nascimento
Valeu por responder as outras questões!
Eu ia perguntar de novo, mas acabei entendendo depois que mexi na função de novo aqui.
Vou ficar de olho nesses livros, de repente algum deles tem no KindleUnlimited. Obrigado mesmo pelas recomendações, eu acho tantos livros que as vezes não sei qual vale a pena ler devido ao meu tempo. Então sempre bom ter umas recomendações.
acontece a todo momento hahaha
Clique aqui para fazer login e interagir na Comunidade :)