I have really specific question. I spent many hours to make it work, but I wasn't successful.
Here is piece of my code, how it looks now:
var mainNames = ["James", "Robert", "John", "Michael", "William", "David", "Peter", "Joseph"];
var genNames = [];
var exceptionNames = ["James", "Michael", "David", "Robert"];
for (var i = 0; i < 4; i++)
{
var idx = Math.floor(Math.random() * names .length);
genNames.push(names [idx]);
}
What I need to do?
mainNames is the main list from which I need to generate 4 unique names, without repetitions. Then, if in the generated list will be found 2 or more exceptionNames, repeat the generation of the mainNames list until the final generated list contain maximum of 1 exceptionNames and no repetitions of the mainNames.
Note: Generated list can contain 0 exceptionNames also, because the generation is random and does not have to generate exceptionNames as an extra names, because they already exists in the mainNames list.
How do I print the final list?
${genNames[0]}, ${genNames[1]}, ${genNames[2]}, ${genNames[3]}
Here are some possible correct outputs:
James, William, John, Peter
Michael, William, Peter, John
Robert, John, William, Peter
David, John, William, Peter
Joseph, Peter, John, William
Note: As you can see in the possible correct outputs are no repetitions of the mainNames and no repetitions of the exceptionNames. And that’s how the above mentioned code should work.
Thanks for possible solutions/answers!
I suppose you could do it like this but it will be a little bit slow don't know how big your name arrays will be in the end.
let mainNames = [
'James',
'Robert',
'John',
'Michael',
'William',
'David',
'Peter',
'Joseph',
]
let genNames = []
const exceptionNames = ['James', 'Michael', 'David', 'Robert']
let exceptionNameAlreadyIncluded = false
while (genNames.length < 4) {
// if the variable exceptionNameAlreadyIncluded is true we filter our the exception names
// to leave only the "normal" ones
const namesToSearch = exceptionNameAlreadyIncluded
? mainNames.filter(
(name) => !exceptionNames.some((exName) => exName === name),
)
: mainNames
// belowe we get random name from our filtered ones push it to the genNamesArray
// and we remove it from mainNames array so there is no duplicates
const nameToAdd = namesToSearch[getRandomInt(namesToSearch.length)]
mainNames = mainNames.filter((name) => name != nameToAdd)
genNames = [...genNames, nameToAdd]
// if the name we found using random is one of exception names we set our
// exceptionNameAlreadyIncluded to true to not include any exception names in future randoms
if (exceptionNames.some((name) => name === nameToAdd))
exceptionNameAlreadyIncluded = true
}
console.log(genNames)
function getRandomInt(max) {
return Math.floor(Math.random() * max)
}
Faster solution
let mainNames = [
'James',
'Robert',
'John',
'Michael',
'William',
'David',
'Peter',
'Joseph',
]
let genNames = []
const exceptionNames = ['James', 'Michael', 'David', 'Robert']
let exceptionNameAlreadyIncluded = false
while (genNames.length < 4) {
const nameIndex = getRandomInt(mainNames.length)
const isExceptionName = exceptionNames.some(
(name) => name === mainNames[nameIndex],
)
if (!exceptionNameAlreadyIncluded || !isExceptionName) {
genNames.push(mainNames[nameIndex])
}
if (isExceptionName) exceptionNameAlreadyIncluded = true
mainNames.splice(nameIndex, 1)
}
console.log(genNames)
function getRandomInt(max) {
return Math.floor(Math.random() * max)
}