js中的随机数组
shuffle array in js
我想在 javascript...
中打乱数组
我第一次写这个函数:
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
let temp0 = arr[Math.floor(Math.random() * arr.length)];
let temp1 = arr[Math.floor(Math.random() * arr.length)];
console.log(temp0); // select random item work correctly
console.log(temp1); // select random item work correctly
if (temp0 === temp1) { //for dont change arr[index] with save value!!!
continue;
}
temp2 = temp0;
temp0 = temp1;
temp1 = temp2;
console.log(temp0); //all temp0, temp1, temp2 are equal!!!
console.log(temp1); //all temp0, temp1, temp2 are equal!!!
console.log(temp2); //all temp0, temp1, temp2 are equal!!!
}
return arr
}
我的算法如下:
- select随机一件
- select另随机一件
- 将两个项目一起切换
但我最终得到 temp0、temp1 和 temp2 都相等!!!
然后我将我的代码更改为这个并且它完美运行
function shuffle1(arr) {
for (i = 0; i < arr.length; i++) {
x = Math.floor(Math.random() * arr.length);
y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[index] with self !!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
return arr
}
唯一发生的变化是:随机创建的索引编号分配给一个变量,然后该变量用于select数组中的一个项目。
谁能帮我理解为什么第一个例子在第二个例子中没有按预期工作?
提前致谢
使用 Fisher 方法应该更有效:
/**
* Shuffles array in place.
* @param {Array} a items An array containing the items.
*/
function shuffle (arr) {
var j, x, index;
for (index = arr.length - 1; index > 0; index--) {
j = Math.floor(Math.random() * (index + 1));
x = arr[index];
arr[index] = arr[j];
arr[j] = x;
}
return arr;
}
原答案:
它不更新的原因是你正在更新的数字没有引用数组中的元素。让我们看看节点 REPL。
我们将创建一个数组并尝试以两种方式更新它,看看是否在数组中看到了更新。
> let a = [1,2,3]
undefined
> let f = a[0] // grab reference to 1st element
undefined
> f
1
> f = 2 // 1. try to update via our variable
2
> a[0]
1 // update has NOT worked
> a[0] = 2 // 2. try to update by array index
2
> a[0]
2 // update has worked
一旦我们将第一个函数更改为通过数组索引更新,两个函数就相同了。
当我更新 f
时,我为它分配了一个新的数字对象,并用 a[0]
打破了 link,它仍然指的是旧数字。在 js 中,数字是不可变的,所以我们不能更新它们,即使我们想更新。
相关:
Is number in JavaScript immutable?
我想在 javascript...
中打乱数组我第一次写这个函数:
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
let temp0 = arr[Math.floor(Math.random() * arr.length)];
let temp1 = arr[Math.floor(Math.random() * arr.length)];
console.log(temp0); // select random item work correctly
console.log(temp1); // select random item work correctly
if (temp0 === temp1) { //for dont change arr[index] with save value!!!
continue;
}
temp2 = temp0;
temp0 = temp1;
temp1 = temp2;
console.log(temp0); //all temp0, temp1, temp2 are equal!!!
console.log(temp1); //all temp0, temp1, temp2 are equal!!!
console.log(temp2); //all temp0, temp1, temp2 are equal!!!
}
return arr
}
我的算法如下:
- select随机一件
- select另随机一件
- 将两个项目一起切换
但我最终得到 temp0、temp1 和 temp2 都相等!!!
然后我将我的代码更改为这个并且它完美运行
function shuffle1(arr) {
for (i = 0; i < arr.length; i++) {
x = Math.floor(Math.random() * arr.length);
y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[index] with self !!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
return arr
}
唯一发生的变化是:随机创建的索引编号分配给一个变量,然后该变量用于select数组中的一个项目。
谁能帮我理解为什么第一个例子在第二个例子中没有按预期工作?
提前致谢
使用 Fisher 方法应该更有效:
/**
* Shuffles array in place.
* @param {Array} a items An array containing the items.
*/
function shuffle (arr) {
var j, x, index;
for (index = arr.length - 1; index > 0; index--) {
j = Math.floor(Math.random() * (index + 1));
x = arr[index];
arr[index] = arr[j];
arr[j] = x;
}
return arr;
}
原答案:
它不更新的原因是你正在更新的数字没有引用数组中的元素。让我们看看节点 REPL。
我们将创建一个数组并尝试以两种方式更新它,看看是否在数组中看到了更新。
> let a = [1,2,3]
undefined
> let f = a[0] // grab reference to 1st element
undefined
> f
1
> f = 2 // 1. try to update via our variable
2
> a[0]
1 // update has NOT worked
> a[0] = 2 // 2. try to update by array index
2
> a[0]
2 // update has worked
一旦我们将第一个函数更改为通过数组索引更新,两个函数就相同了。
当我更新 f
时,我为它分配了一个新的数字对象,并用 a[0]
打破了 link,它仍然指的是旧数字。在 js 中,数字是不可变的,所以我们不能更新它们,即使我们想更新。
相关: Is number in JavaScript immutable?