我有两个阵列
var mp3 = ['sing.mp3','song.mp3','tune.mp3','jam.mp3',etc];
var ogg = ['sing.ogg','song.ogg','tune.ogg','jam.ogg',etc];
我需要对两个数组进行混洗,以便它们以相同的方式出现,例如:
var mp3 = ['tune.mp3','song.mp3','jam.mp3','sing.mp3',etc];
var ogg = ['tune.ogg','song.ogg','jam.ogg','sing.ogg',etc];
stackoverflow上有一些帖子以不同的方式对数组进行洗牌 - this one is pretty great - 但它们都没有演示如何以相同的方式对两个数组进行混洗。
日Thnx!
答案 0 :(得分:2)
为Fisher-Yates shuffle添加一个额外的参数。 (假设您的数组长度相等)
var mp3 = ["sing.mp3", "song.mp3"];
var ogg = ["sing.ogg", "song.ogg"];
function shuffle(obj1, obj2) {
var index = obj1.length;
var rnd, tmp1, tmp2;
while (index) {
rnd = Math.floor(Math.random() * index);
index -= 1;
tmp1 = obj1[index];
tmp2 = obj2[index];
obj1[index] = obj1[rnd];
obj2[index] = obj2[rnd];
obj1[rnd] = tmp1;
obj2[rnd] = tmp2;
}
}
shuffle(mp3, ogg);
console.log(mp3, ogg);
<强>更新强>
如果您要支持更多数组(如注释中所示),那么您可以按如下方式修改Fisher-Yates(以及执行一些检查以确保参数是Array并且它们的长度匹配)
var isArray = Array.isArray || function(value) {
return {}.toString.call(value) !== "[object Array]"
};
var mp3 = ["sing.mp3", "song.mp3", "tune.mp3", "jam.mp3"];
var ogg = ["sing.ogg", "song.ogg", "tune.ogg", "jam.ogg"];
var acc = ["sing.acc", "song.acc", "tune.acc", "jam.acc"];
var flc = ["sing.flc", "song.flc", "tune.flc", "jam.flc"];
function shuffle() {
var arrLength = 0;
var argsLength = arguments.length;
var rnd, tmp;
for (var index = 0; index < argsLength; index += 1) {
if (!isArray(arguments[index])) {
throw new TypeError("Argument is not an array.");
}
if (index === 0) {
arrLength = arguments[0].length;
}
if (arrLength !== arguments[index].length) {
throw new RangeError("Array lengths do not match.");
}
}
while (arrLength) {
rnd = Math.floor(Math.random() * arrLength);
arrLength -= 1;
for (argsIndex = 0; argsIndex < argsLength; argsIndex += 1) {
tmp = arguments[argsIndex][arrLength];
arguments[argsIndex][arrLength] = arguments[argsIndex][rnd];
arguments[argsIndex][rnd] = tmp;
}
}
}
shuffle(mp3, ogg, acc, flc);
console.log(mp3, ogg, acc, flc);
答案 1 :(得分:1)
从该示例中,只需添加第二个参数(第二个数组)并对两个阵列执行操作。你只需要添加和使用第二个临时值,这样你就不会覆盖你的临时值。
这应该可以确定阵列的长度是相同的长度:
function shuffle(array, array2) {
var counter = array.length, temp, temp2, index;
// While there are elements in the array
while (counter > 0) {
// Pick a random index
index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
temp = array[counter];
temp2 = array2[counter];
array[counter] = array[index];
array2[counter] = array2[index];
array[index] = temp;
array2[index] = temp2;
}
}
答案 2 :(得分:1)
我会认真考虑重组你跟踪信息的方式,但一般来说你可以将洗牌本身与被洗牌的东西分开。您需要一个函数来生成随机排列,然后需要一个函数来将排列应用于数组。
function shuffle(o) { //v1.0
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
function permutation( length ) {
var p = [], i;
for (i = 0; i < length; ++i) p[i] = i;
return shuffle(p);
}
function permute( a, p ) {
var r = [];
for (var i = 0; i < a.length; ++i)
r.push(a[p[i]]);
for (i = 0; i < a.length; ++i)
a[i] = r[i];
}
然后,您可以创建一个随机排列并将其应用于您想要的任何列表(正确长度)。
var p = permutation( mp3.length );
permute(mp3, p);
permute(ogg, p);
permute(aac, p);
// etc
(从OP中链接的SO问题中获取随机播放功能。)
答案 3 :(得分:0)
如果您有两个长度为2的数组,@ Xotic750s函数始终返回相同的值。 UseMath.round而不是Math.floor。
function shuffle_two_arrays_identically(arr1, arr2){
"use strict";
var l = arr1.length,
i = 0,
rnd,
tmp1,
tmp2;
while (i < l) {
rnd = Math.round(Math.random() * i)
tmp1 = arr1[i]
tmp2 = arr2[i]
arr1[i] = arr1[rnd]
arr2[i] = arr2[rnd]
arr1[rnd] = tmp1
arr2[rnd] = tmp2
i += 1
}}
答案 4 :(得分:0)
<script>
var arrayList= ['a','b','c','d','e','f','g'];
arrayList.sort(function(){
return 0.5 - Math.random()
})
document.getElementById("output").innerHTML = arrayList;
<script>