随机排列 JavaScript 中的字符串数组,重复元素至少相隔两个元素
Shuffle arrays of strings in JavaScript with repeated elements that are at least two elements apart
我有两个字符串数组:
var array1 = ["word1", "word2", "word3", "word4", "word5", "word6"];
var array2 = ["word7", "word8"];
我需要将这些数组连接成一个新数组,并以随机顺序排列元素。但是,array2
中的元素应该在这个新数组中重复出现两次,并且给定元素的重复必须至少相隔两个元素。
这是满足这些条件的示例结果:
["word7", "word3", "word8", "word7", "word1", "word4", "word6", "word8", "word5", "word2"];
所有元素的顺序都是随机的,重复的元素之间至少有两个其他元素。我如何编写一个函数(最好不使用额外的库)来创建满足上述条件的随机排序数组?我试过扩展标准排列算法(例如 Fisher-Yates),但由于我对 JS 不是很熟悉,所以我在实现上遇到了问题。
非常感谢任何帮助 - 谢谢!
最简单的可能是分两步完成。
- 使用标准 fisher-yates 算法随机播放
array1
。
- 在满足条件的随机位置插入元素
类似下面的内容(我假设,您可以实现 fisher yates,因此我没有在此处包含它,只是制作了一个(未打乱的)数组副本)
let array1 = [1,2,3,4,5,6,7]
let array2 = [8,9]
let rand = (n) => Math.floor(Math.random()*n);
//let shuffled = fisheryates(array1);
let shuffled = array1.slice(); //just make a copy of the array
while (array2.length) {
let e = array2.splice(rand(array2.length), 1)[0];
let i1 = shuffled.length == 2
? 0
: rand(shuffled.length + 1);
let i2 = 0;
do {
i2 = shuffled.length == 2
? 2
: rand(shuffled.length + 1);
}
while (Math.abs(i1 - i2) < 2)
if (i1 < i2) {
shuffled.splice(i2, 0, e);
shuffled.splice(i1, 0, e);
} else {
shuffled.splice(i1, 0, e);
shuffled.splice(i2, 0, e);
}
}
console.log(shuffled)
它是如何工作的:
以随机顺序遍历 array2
中的所有元素
你得到一个用于插入第一个元素的随机索引。如果 shuffled
只有 2 个元素,则唯一有效的索引是 0 和 2(因为这是唯一的方法,中间至少有两个元素)。我在这里使用 shuffled.length + 1
,因为这样也可以在数组末尾插入元素。
然后你需要找到另一个索引,它与第一个索引至少相差两个元素。最简单(但不一定是最快)的方法就是尝试直到找到索引。
在数组中插入元素时,必须先插入索引较大的元素,否则上边的元素会出现在错误的位置
如果 array1
只有一个元素,则 array2
中至少需要两个元素才能生成有效输出,但您可以在特殊情况下手动执行此操作。
let array1 = ['a']
let array2 = ['x', 'y', ...]
let shuffled = ['x', 'y', 'a', 'x', 'y'] //or yxayx
我有两个字符串数组:
var array1 = ["word1", "word2", "word3", "word4", "word5", "word6"];
var array2 = ["word7", "word8"];
我需要将这些数组连接成一个新数组,并以随机顺序排列元素。但是,array2
中的元素应该在这个新数组中重复出现两次,并且给定元素的重复必须至少相隔两个元素。
这是满足这些条件的示例结果:
["word7", "word3", "word8", "word7", "word1", "word4", "word6", "word8", "word5", "word2"];
所有元素的顺序都是随机的,重复的元素之间至少有两个其他元素。我如何编写一个函数(最好不使用额外的库)来创建满足上述条件的随机排序数组?我试过扩展标准排列算法(例如 Fisher-Yates),但由于我对 JS 不是很熟悉,所以我在实现上遇到了问题。
非常感谢任何帮助 - 谢谢!
最简单的可能是分两步完成。
- 使用标准 fisher-yates 算法随机播放
array1
。 - 在满足条件的随机位置插入元素
类似下面的内容(我假设,您可以实现 fisher yates,因此我没有在此处包含它,只是制作了一个(未打乱的)数组副本)
let array1 = [1,2,3,4,5,6,7]
let array2 = [8,9]
let rand = (n) => Math.floor(Math.random()*n);
//let shuffled = fisheryates(array1);
let shuffled = array1.slice(); //just make a copy of the array
while (array2.length) {
let e = array2.splice(rand(array2.length), 1)[0];
let i1 = shuffled.length == 2
? 0
: rand(shuffled.length + 1);
let i2 = 0;
do {
i2 = shuffled.length == 2
? 2
: rand(shuffled.length + 1);
}
while (Math.abs(i1 - i2) < 2)
if (i1 < i2) {
shuffled.splice(i2, 0, e);
shuffled.splice(i1, 0, e);
} else {
shuffled.splice(i1, 0, e);
shuffled.splice(i2, 0, e);
}
}
console.log(shuffled)
它是如何工作的:
以随机顺序遍历 array2
中的所有元素
你得到一个用于插入第一个元素的随机索引。如果
shuffled
只有 2 个元素,则唯一有效的索引是 0 和 2(因为这是唯一的方法,中间至少有两个元素)。我在这里使用shuffled.length + 1
,因为这样也可以在数组末尾插入元素。然后你需要找到另一个索引,它与第一个索引至少相差两个元素。最简单(但不一定是最快)的方法就是尝试直到找到索引。
在数组中插入元素时,必须先插入索引较大的元素,否则上边的元素会出现在错误的位置
如果 array1
只有一个元素,则 array2
中至少需要两个元素才能生成有效输出,但您可以在特殊情况下手动执行此操作。
let array1 = ['a']
let array2 = ['x', 'y', ...]
let shuffled = ['x', 'y', 'a', 'x', 'y'] //or yxayx