随机排列 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 不是很熟悉,所以我在实现上遇到了问题。

非常感谢任何帮助 - 谢谢!

最简单的可能是分两步完成。

  1. 使用标准 fisher-yates 算法随机播放 array1
  2. 在满足条件的随机位置插入元素

类似下面的内容(我假设,您可以实现 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