首页 > 解决方案 > 如何使用 Fisher-Yates 对 JavaScript 数组进行洗牌?

问题描述

我正在尝试根据Awais Mirza的教程修改此测验应用程序

我想从主数组中随机选择问题并将其推送到脚本用于填充问题的选择数组中,因此每次测验运行时,测验都会从主数组中随机给出一组问题。我想我可以在将选定数量的问题推入选择数组之前使用 Fisher-Yates shuffle 随机化主数组。

为什么 Fisher-Yates shuffle 对这个数组起作用;

var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

var i = arr.length, j, temp;
while(--i > 0){
    j = Math.floor(Math.random()*(i+1));
    temp = arr[j];
    arr[j] = arr[i];
    arr[i] = temp;
}
console.log(arr);

但不是这个数组?

var Questions = [
    new Question("What comes after 1?", ["1", "2","3", "4"], "2"),
    new Question("What comes after 2?", ["1", "2", "3", "4"], "3"),
    new Question("What comes after 3?", ["1", "2", "3", "4"], "4")
];

标签: javascriptarrayssortingshuffle

解决方案


Fisher-Yates 算法仅适用于数组索引,因此您不需要根据数组内容进行不同的实现

为了说明我已经将排序代码移动到一个函数中以便可以重用它:

function shuffle(arr) {
  var i = arr.length, j, temp;
  while(--i > 0){
    j = Math.floor(Math.random()*(i+1));
    temp = arr[j];
    arr[j] = arr[i];
    arr[i] = temp;
  }
}

class Question {
  constructor(title, options, solution) {
    this.title = title;
    this.options = options;
    this.solution = solution;
  }
}

var integerArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var questions = [
    new Question("What comes after 1?", ["1", "2","3", "4"], "2"),
    new Question("What comes after 2?", ["1", "2", "3", "4"], "3"),
    new Question("What comes after 3?", ["1", "2", "3", "4"], "4")
];
shuffle(integerArray);
shuffle(questions);
console.log(integerArray, questions);


推荐阅读