Javascript 如何在JS中专门洗牌数组?

Javascript 如何在JS中专门洗牌数组?,javascript,arrays,Javascript,Arrays,如果我有这个数组,并且想洗牌,我知道使用Fisher-Yates洗牌,但是我如何以更有组织的方式洗牌呢 比如,我如何洗牌,但也要保证洗牌后0永远不会出现在数组的第一个位置,1永远不会出现在数组的第二个位置,2永远不会出现在第三个位置,等等。考虑使用Sattolo的算法,如前所述 它本质上与Fisher Yates相同,但有一个小小的变化,导致数组元素无法保持在它们自己的位置,这似乎就是您所描述的。var finalArray=[]; var testArray = [0, 1, 2, 3, 4,

如果我有这个数组,并且想洗牌,我知道使用Fisher-Yates洗牌,但是我如何以更有组织的方式洗牌呢


比如,我如何洗牌,但也要保证洗牌后
0
永远不会出现在数组的第一个位置,
1
永远不会出现在数组的第二个位置,
2
永远不会出现在第三个位置,等等。

考虑使用Sattolo的算法,如前所述

它本质上与Fisher Yates相同,但有一个小小的变化,导致数组元素无法保持在它们自己的位置,这似乎就是您所描述的。

var finalArray=[];
var testArray = [0, 1, 2, 3, 4, 5, 6]
函数getUniqueNumber(){ var uniqueNumber=Math.floor(Math.random()*6)+0; var doesExist=finalArray.indexOf(uniqueNumber)=-1; 如果(!性别歧视){ 返回getUniqueNumber(); }否则{ 返回唯一编号; } } 函数generateTastaray(){ 对于(变量i=0;i<6;i++){ finalArray.push(getUniqueNumber()); } 控制台日志(finalArray); }
这将始终生成一个测试数组,唯一地将索引弄乱。

/**fisher-yates,如维基百科上所示
var finalArray = [];

function getUniqueNumber() {
    var uniqueNumber = Math.floor(Math.random() * 6) + 0;
    var doesExist = finalArray.indexOf(uniqueNumber) === -1;

    if (!doesExist) {
        return getUniqueNumber();
    } else {
        return uniqueNumber;
    }
}

function generateTestArray() {
    for (var i = 0; i < 6; i++) {
        finalArray.push(getUniqueNumber());
    }
    console.log(finalArray);
}
*因为我来自n−一点一滴 *j← 随机整数,使得0≤ J≤ 我 *交换a[j]和a[i] */ /**如上所述的改良fisher-yates *因为我来自n−一点一滴 *j← 随机整数,使得0≤ J≤ i、 j!=i、 a[j]!=i、 a[我]!=J *交换a[j]和a[i](其中a[j]!=i) */ 让modifiedFYShuffle=(数组)=>{ 让交换=(i,j)=>{ 设tmp=array[i]; 数组[i]=数组[j]; 数组[j]=tmp; } for(设i=array.length-1;i>=0;--i){ 设j=i; 而(j==i | |数组[j]==i | |数组[i]==j){ j=Math.floor(Math.random()*array.length); } 互换(i,j) } } 让makeArray=()=>{ 让数组=[]; for(设i=0;i<10;++i){ 数组[i]=i; } 返回数组; } for(设i=0;i<10;++i){ 让数组=makeArray(); 修改的yshuffle(数组); console.log(数组) }
为什么不在不包括您所描述内容的阵列切片上使用fisher-yates?然后再加入他们?
/** fisher yates as seen on wikipedia
 * for i from n−1 downto 1 do
 *   j ← random integer such that 0 ≤ j ≤ i
 *   exchange a[j] and a[i] 
 */

/** modified fisher yates as described
 * for i from n−1 downto 1 do
 *   j ← random integer such that 0 ≤ j ≤ i, j != i, a[j] != i, a[i] != j
 *   exchange a[j] and a[i] (where a[j] != i)
 */

let modifiedFYShuffle = (array) => {
  let swap = (i, j) => {
    let tmp = array[i];
    array[i] = array[j];
    array[j] = tmp;
  }
  for (let i = array.length - 1; i >= 0; --i) {
    let j = i;
    while (j === i || array[j] === i || array[i] === j) {
      j = Math.floor(Math.random() * array.length);
    }
    swap(i, j)
  }
}

let makeArray = () => {
  let array = [];
  for (let i = 0; i < 10; ++i) {
    array[i] = i;
  }
  return array;
}

for (let i = 0; i < 10; ++i) {
  let array = makeArray();
  modifiedFYShuffle(array);
  console.log(array)
}