我有两个字符串数组:
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
进行混叠 - 在满足条件的任意位置插入元素
Ie类似于以下内容(我认为,您可以实现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