如何更改Javascript数组以确保每个Index在新数组中处于新位置?

Ric*_*ett 12 javascript arrays shuffle underscore.js

我有一个对象数组,就像这样.

var usersGoing = [
    { user: 0 },
    { user: 1 },
    { user: 2 },
    { user: 3 },
    { user: 4 }
];
Run Code Online (Sandbox Code Playgroud)

我需要对这个数组进行洗牌,以便没有任何Object保留在与实例化时相同的索引中,如下所示:

[
    { user: 3 },
    { user: 2 },
    { user: 4 },
    { user: 0 },
    { user: 1 }
]
Run Code Online (Sandbox Code Playgroud)

结果是以这种方式对结果数组进行排序是非常重要的,因为这些用户对象中的每一个都将被分配给不同的用户对象.

我尝试了一些不同的排序算法,包括Fisher-Yates,我尝试过使用Underscore.js'_.shuffle(),这个变种来自Kirupa Shuffling一个JavaScript中的数组:

function shuffleFY(input) {
    for (var i = input.length-1; i >=0; i--) {
        var randomIndex = Math.floor(Math.random()*(i+1)); 
        var itemAtIndex = input[randomIndex]; 

        input[randomIndex] = input[i]; 
        input[i] = itemAtIndex;
    }
    return input;
}
Run Code Online (Sandbox Code Playgroud)

我没有尝试过任何工作.救命?

更新:我在下面标记了一个正确答案,因为正确遵循了Sattolo Cycle的关键点.此外,这不是Shuffles随机数的重复,在Javascript/PHP中没有重复,因为此问题还有对结果数组的额外要求,不仅不包含重复项,而且还不能包含相同初始索引位置的项.

Sha*_*ank 5

您发布了一个用 Python 编写的 Sattolo 算法的链接:

from random import randrange

def sattoloCycle(items):
    i = len(items)
    while i > 1:
        i = i - 1
        j = randrange(i)  # 0 <= j <= i-1
        items[j], items[i] = items[i], items[j]
    return
Run Code Online (Sandbox Code Playgroud)

这里它被翻译成 JavaScript:

function sattoloCycle(items) {
  for(var i = items.length; i-- > 1; ) {
    var j = Math.floor(Math.random() * i);
    var tmp = items[i];
    items[i] = items[j];
    items[j] = tmp;
  }
}
Run Code Online (Sandbox Code Playgroud)