以相同的方式打乱多个javascript数组

Shuffle multiple javascript arrays in the same way

本文关键字:javascript 数组 方式打      更新时间:2023-09-26

我有两个数组

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上有几篇文章以不同的方式打乱数组——这篇文章非常棒——但没有一篇文章演示如何以相同的方式打乱两个数组。

thnx!

在Fisher-Yates洗牌中添加一个额外的参数。(假设您的阵列长度相等)

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);

在该示例中,只需添加第二个参数(第二个数组)并对两个数组执行操作。您只需要添加并使用第二个temp,这样就不会覆盖您的temp。

假设阵列的长度相同,这就可以完成任务:

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;
    }
}

我会认真考虑重新构建跟踪信息的方式,但通常情况下,您可以将shuffle本身与被shuffle的东西分开。您需要一个函数来生成随机排列,然后需要一个将排列应用于数组的函数。

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

(Shuffle函数取自OP中链接的SO问题。)

如果有两个长度为2的数组,@Xotic750s函数总是返回相同的值。使用Math.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
}}

<script>
var arrayList= ['a','b','c','d','e','f','g'];
arrayList.sort(function(){
    return 0.5 - Math.random()
})
document.getElementById("output").innerHTML  = arrayList;
<script>