从数组中拼接随机名称,直到数组为空
Splicing random names from array until array is empty
我正在尝试随机选择两个名称并将它们相加。每次选择名称时,都应将其从数组中删除。函数应该 运行 直到数组为空。输出应该是在字符串或数组中配对在一起的所有名称。
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank']
//var to pick two random names from an array
function pickTwo(arr) {
let random = Math.floor(Math.random() * arr.length);
let random2 = Math.floor(Math.random() * arr.length);
while (random === random2) {
random2 = Math.floor(Math.random() * arr.length);
}
//remove random and random2 from array
//run untill there are no more names in the array
while (arr.length > 0) {
arr.splice(random, 1);
arr.splice(random2, 1);
return [arr[random], arr[random2]];
}
}
console.log(pickTwo(names));
console.log(names);
首先确保删除从数组中随机选择的 2 个名称。您拥有的函数不会执行此操作,因为从中删除名称的 arr 变量是该函数的本地变量。考虑使用在函数之前启动的全局变量 groovy,或者从函数返回 arr 变量,然后再次将其发送回函数。之后,您只需创建一个运行 pickTwo 函数的 while 循环,直到 groovy.
中没有任何内容为止
var array = [];
while(groovy.length>1){
array.push(pickTwo(groovy));
}
每次while (arr.length > 0)
循环都需要得到新的随机数。否则,拼接后你的随机索引可能在数组之外,你得到 undefined
.
您需要将循环中选择的每对数字推入另一个数组,return那个数组作为最终结果。
另外,当你第一次拼接时,random
之后的所有索引都会向下移动。如果 random2
高于 random
,您将拼接错误的元素。你应该先把高的拼接出来。
拼接后,arr[random]
和 arr[random2]
不引用所选元素,因为您已将它们从数组中删除。 splice()
return删除的元素,你应该使用那个结果。
做这件事的一个更简单的方法是随机排列数组。然后就得到每对顺序元素。
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank']
//var to pick two random names from an array
function pickTwo(arr) {
let result = [];
while (arr.length > 0) {
let random = Math.floor(Math.random() * arr.length);
let random2 = Math.floor(Math.random() * arr.length);
while (random === random2) {
random2 = Math.floor(Math.random() * arr.length);
}
//remove random and random2 from array
//run untill there are no more names in the array
let val1, val2;
if (random < random2) {
val2 = arr.splice(random2, 1)[0];
val1 = arr.splice(random, 1)[0];
} else {
val1 = arr.splice(random, 1)[0];
val2 = arr.splice(random2, 1)[0];
}
result.push([val1, val2]);
}
return result;
}
console.log(pickTwo(names));
console.log(names);
您的代码中存在一些问题:
当random
和random2
这样random + 1 == random2
和random2 == arr.length - 1
时,那么第二个splice
就没有效果了,因为数组大小已经减小。
当您在 while
循环体中 return
时,该循环将永远不会有第二次迭代。
我建议采用不同的方法:
- 随机打乱数组
- Return 打乱后的数组中的连续对
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
function pickTwo(arr) {
arr = shuffle([...arr]);
return Array.from({length: arr.length >> 1}, (_, i) =>
arr.slice(i*2, i*2+2)
);
}
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'];
console.log(pickTwo(names));
一种稍微修改过的方法,它使用一个单独的接受数组长度的随机化函数,主函数只是将拼接的结果从数组推入输出数组(并将结果展平,因为每个拼接都会 return 它自己的数组),然后 return 输出数组主数组为空。
const names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'];
function rnd(len) {
return Math.floor(Math.random() * len);
}
function pickTwo(arr) {
const out = [];
while (arr.length > 0) {
out.push([
arr.splice(rnd(arr.length), 1),
arr.splice(rnd(arr.length), 1)
].flat());
}
return out;
}
console.log(pickTwo(names));
其他文档
我正在尝试随机选择两个名称并将它们相加。每次选择名称时,都应将其从数组中删除。函数应该 运行 直到数组为空。输出应该是在字符串或数组中配对在一起的所有名称。
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank']
//var to pick two random names from an array
function pickTwo(arr) {
let random = Math.floor(Math.random() * arr.length);
let random2 = Math.floor(Math.random() * arr.length);
while (random === random2) {
random2 = Math.floor(Math.random() * arr.length);
}
//remove random and random2 from array
//run untill there are no more names in the array
while (arr.length > 0) {
arr.splice(random, 1);
arr.splice(random2, 1);
return [arr[random], arr[random2]];
}
}
console.log(pickTwo(names));
console.log(names);
首先确保删除从数组中随机选择的 2 个名称。您拥有的函数不会执行此操作,因为从中删除名称的 arr 变量是该函数的本地变量。考虑使用在函数之前启动的全局变量 groovy,或者从函数返回 arr 变量,然后再次将其发送回函数。之后,您只需创建一个运行 pickTwo 函数的 while 循环,直到 groovy.
中没有任何内容为止var array = [];
while(groovy.length>1){
array.push(pickTwo(groovy));
}
每次while (arr.length > 0)
循环都需要得到新的随机数。否则,拼接后你的随机索引可能在数组之外,你得到 undefined
.
您需要将循环中选择的每对数字推入另一个数组,return那个数组作为最终结果。
另外,当你第一次拼接时,random
之后的所有索引都会向下移动。如果 random2
高于 random
,您将拼接错误的元素。你应该先把高的拼接出来。
拼接后,arr[random]
和 arr[random2]
不引用所选元素,因为您已将它们从数组中删除。 splice()
return删除的元素,你应该使用那个结果。
做这件事的一个更简单的方法是随机排列数组。然后就得到每对顺序元素。
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank']
//var to pick two random names from an array
function pickTwo(arr) {
let result = [];
while (arr.length > 0) {
let random = Math.floor(Math.random() * arr.length);
let random2 = Math.floor(Math.random() * arr.length);
while (random === random2) {
random2 = Math.floor(Math.random() * arr.length);
}
//remove random and random2 from array
//run untill there are no more names in the array
let val1, val2;
if (random < random2) {
val2 = arr.splice(random2, 1)[0];
val1 = arr.splice(random, 1)[0];
} else {
val1 = arr.splice(random, 1)[0];
val2 = arr.splice(random2, 1)[0];
}
result.push([val1, val2]);
}
return result;
}
console.log(pickTwo(names));
console.log(names);
您的代码中存在一些问题:
当
random
和random2
这样random + 1 == random2
和random2 == arr.length - 1
时,那么第二个splice
就没有效果了,因为数组大小已经减小。当您在
while
循环体中return
时,该循环将永远不会有第二次迭代。
我建议采用不同的方法:
- 随机打乱数组
- Return 打乱后的数组中的连续对
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
function pickTwo(arr) {
arr = shuffle([...arr]);
return Array.from({length: arr.length >> 1}, (_, i) =>
arr.slice(i*2, i*2+2)
);
}
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'];
console.log(pickTwo(names));
一种稍微修改过的方法,它使用一个单独的接受数组长度的随机化函数,主函数只是将拼接的结果从数组推入输出数组(并将结果展平,因为每个拼接都会 return 它自己的数组),然后 return 输出数组主数组为空。
const names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'];
function rnd(len) {
return Math.floor(Math.random() * len);
}
function pickTwo(arr) {
const out = [];
while (arr.length > 0) {
out.push([
arr.splice(rnd(arr.length), 1),
arr.splice(rnd(arr.length), 1)
].flat());
}
return out;
}
console.log(pickTwo(names));
其他文档