jQuery - 如何在数组数组中随机化

jQuery - How to randomize within an array of arrays?

本文关键字:数组 随机化 jQuery      更新时间:2023-09-26

我正在构建一个游戏,在 4x4 网格墙中提供答案,答案最初将以四人为一组,需要在每场比赛开始时随机化。然后,玩家必须将答案重新排列成组(如果这没有意义,http://www.puzzgrid.com/grid/7279,展示了我想要实现的示例)。

我设置了一个带有答案数组的网格,如下所示:

var grid = [
  ['oak','cedar','fir','pine'],
  ['red','blue','green','yellow'],
  ['villa','spurs','city','united'],
  ['table','chair','door','stool']
];

使用费舍尔-耶茨洗牌如下,我可以让网格随机化数组:

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

问题在于它只打乱整行,而不是每个数组中的项目,因此,例如,"椅子"永远不会在"城市"旁边。有人对如何做到这一点有任何建议吗?

椅子永远不会在城市旁边,因为您不会更改行中的元素,而只是打乱行。

您可以使用适用于整个矩阵的修改算法。

var grid = [
  ['oak','cedar','fir','pine'],
  ['red','blue','green','yellow'],
  ['villa','spurs','city','united'],
  ['table','chair','door','stool']
];
var n = 4, m = 4, i = n*m, j, temp;
while(--i>0){
    j = Math.floor(Math.random()*(i+1));
    temp = grid[Math.floor(j/n)][j%m];
    grid[Math.floor(j/n)][j%m] = grid[Math.floor(i/n)][i%m];
    grid[Math.floor(i/m)][i%m] = temp;
}
console.log(grid);

https://jsfiddle.net/vwey4yb2/1/

尝试使用嵌套while循环,Array.prototype.splice()

var grid = [
  ['oak', 'cedar', 'fir', 'pine'],
  ['red', 'blue', 'green', 'yellow'],
  ['villa', 'spurs', 'city', 'united'],
  ['table', 'chair', 'door', 'stool']
];
var copy = grid.slice().join(" ").replace(/,/g, " ").split(" ");
var res = [];
while (copy.length) {
  var arr = [];
  while (arr.length < 4) {
    var j = copy.splice(Math.floor(Math.random() * copy.length), 1)[0];
    arr.push(j)
  };
  res.push(arr)
}
document.querySelector("pre").textContent = JSON.stringify(res, null, 2);
<pre></pre>

感谢大家的帮助,我们最后在数组上使用 .concat 对其进行排序,如下所示:

var answers = [
  ["Oak","Cedar","Fir","Pine"], // grid[0][0], grid[0][1]
  ["Red","Blue","Green","Yellow"],// grid[1][0], grid[1][1]
  ["Villa","Spurs","City","United"],
  ["Table","Chair","Door","Stool"]
];
var grid = answers.reduce(function(prev, current) {
  return prev.concat(current);
}, []);