有异常的唯一数组
Unique array with exception
我有一个非常具体的问题。我花了很多时间让它工作,但我没有成功。
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 是主要列表,我需要从中生成 4 个唯一名称,不要重复。然后,如果在生成的列表中会发现2个或更多的exceptionNames,重复mainNames列表的生成,直到最终生成的列表最多包含1 exceptionNames 并且没有重复 mainNames.
注意:生成的列表可以包含0个exceptionNames,因为生成是随机的并且不必生成 exceptionNames 作为额外的名称,因为它们已经存在于 mainNames list.[=16= 中]
How do I print the final list?
${genNames[0]}, ${genNames[1]}, ${genNames[2]}, ${genNames[3]}
Here are some possible correct outputs:
詹姆斯、威廉、约翰、彼得
迈克尔、威廉、彼得、约翰
罗伯特、约翰、威廉、彼得
大卫、约翰、威廉、彼得
约瑟夫、彼得、约翰、威廉
注意: 正如您在可能的正确输出中看到的那样,没有重复 mainNames 并且没有重复 exceptionNames。这就是上面提到的代码应该如何工作。
感谢 solutions/answers!
对初始数组和 select 前 4 项进行随机排序。然后将项目与异常数组进行比较,确保计数为 1 或更小。不断重复找到解决方案。
var mainNames = ["James", "Robert", "John", "Michael", "William", "David", "Peter", "Joseph"];
var exceptionNames = ["James", "Michael", "David", "Robert"];
let names = [], count = 4
while(count>1) {
names = mainNames.map(i => ({ s: Math.random(), i })).sort((a,b) => a.s - b.s).map(({i})=> i).slice(4);
count = names.filter(n => exceptionNames.includes(n)).length;
}
console.log(names.join(','))
我想你可以这样做,但它会有点慢不知道你的名字数组最终会有多大。
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)
}
更快的解决方案
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)
}
首先,您的代码中似乎存在一些语法错误 - 例如,在您尝试使用变量之前,“名称”永远不会 created/initialized。我认为它应该是“mainNames”。
变量和方法调用之间也不能有空格。例如'names .length' 应该是 'names.length' 而 'names [idx]' 应该是 'names[idx].
除此之外,您还缺少任何方法来检查所选名称是否已在列表中。获得随机索引后,将其转换为一个值,然后在继续之前检查它是否符合您列出的标准(如果它不在列表中)。有多种方法可以做到这一点,但这是您缺少的最重要的一步。
然后您还需要添加一种方法来检查您的异常名称是否只出现一次。同样,有几种方法可以做到这一点,但目前完全没有这一步。
如果您遇到这样的问题,我强烈建议您在直接进入实际代码之前,先在 pseudo-code 中(用通俗易懂的注释)写下您需要完成的步骤。这真的可以帮助保持事情的顺利进行。
我有一个非常具体的问题。我花了很多时间让它工作,但我没有成功。
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 是主要列表,我需要从中生成 4 个唯一名称,不要重复。然后,如果在生成的列表中会发现2个或更多的exceptionNames,重复mainNames列表的生成,直到最终生成的列表最多包含1 exceptionNames 并且没有重复 mainNames.
注意:生成的列表可以包含0个exceptionNames,因为生成是随机的并且不必生成 exceptionNames 作为额外的名称,因为它们已经存在于 mainNames list.[=16= 中]
How do I print the final list?
${genNames[0]}, ${genNames[1]}, ${genNames[2]}, ${genNames[3]}
Here are some possible correct outputs:
詹姆斯、威廉、约翰、彼得
迈克尔、威廉、彼得、约翰
罗伯特、约翰、威廉、彼得
大卫、约翰、威廉、彼得
约瑟夫、彼得、约翰、威廉
注意: 正如您在可能的正确输出中看到的那样,没有重复 mainNames 并且没有重复 exceptionNames。这就是上面提到的代码应该如何工作。
感谢 solutions/answers!
对初始数组和 select 前 4 项进行随机排序。然后将项目与异常数组进行比较,确保计数为 1 或更小。不断重复找到解决方案。
var mainNames = ["James", "Robert", "John", "Michael", "William", "David", "Peter", "Joseph"];
var exceptionNames = ["James", "Michael", "David", "Robert"];
let names = [], count = 4
while(count>1) {
names = mainNames.map(i => ({ s: Math.random(), i })).sort((a,b) => a.s - b.s).map(({i})=> i).slice(4);
count = names.filter(n => exceptionNames.includes(n)).length;
}
console.log(names.join(','))
我想你可以这样做,但它会有点慢不知道你的名字数组最终会有多大。
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)
}
更快的解决方案
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)
}
首先,您的代码中似乎存在一些语法错误 - 例如,在您尝试使用变量之前,“名称”永远不会 created/initialized。我认为它应该是“mainNames”。
变量和方法调用之间也不能有空格。例如'names .length' 应该是 'names.length' 而 'names [idx]' 应该是 'names[idx].
除此之外,您还缺少任何方法来检查所选名称是否已在列表中。获得随机索引后,将其转换为一个值,然后在继续之前检查它是否符合您列出的标准(如果它不在列表中)。有多种方法可以做到这一点,但这是您缺少的最重要的一步。
然后您还需要添加一种方法来检查您的异常名称是否只出现一次。同样,有几种方法可以做到这一点,但目前完全没有这一步。
如果您遇到这样的问题,我强烈建议您在直接进入实际代码之前,先在 pseudo-code 中(用通俗易懂的注释)写下您需要完成的步骤。这真的可以帮助保持事情的顺利进行。