我有一个这样的数组:

var arr1 = ["a", "b", "c", "d"];

我如何随机化/打乱它?


当前回答

使用ES6功能的现代短内联解决方案:

['a','b','c','d'].map(x => [Math.random(), x]).sort(([a], [b]) => a - b).map(([_, x]) => x);

(出于教育目的)

其他回答

可理解的洗牌数组元素的方法设arr1=[“a”,“b”,“c”,“d”];函数洗牌(数组){let currentIndex=array.length;while(currentIndex!=0){let randomIndex=Math.floor(Math.random()*array.length);当前索引-=1;let temp=数组[currentIndex];array[currentIndex]=array[randomIndex];array[randomIndex]=临时;}返回数组;}设arr2=洗牌(arr1);arr2.forEach(元素=>console.log(元素));

我在考虑在控制台上粘贴oneliner。sort的所有技巧都给出了错误的结果,下面是我的实现:

 ['Bob', 'Amy', 'Joy'].map((person) => `${Math.random().toFixed(10)}${person}`).sort().map((person) => person.substr(12));

但不要在生产代码中使用它,它不是最佳的,只适用于字符串。

我认为还没有人给出一个可以在不扩展Array原型的情况下连接起来的解决方案(这是一个糟糕的做法)。使用稍微鲜为人知的reduce(),我们可以轻松地以允许串联的方式进行混洗:

var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle).map(n => n*n);

您可能希望传递第二个参数[],否则如果尝试在空数组上执行此操作,则会失败:

// Both work. The second one wouldn't have worked as the one above
var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle, []).map(n => n*n);
var randomsquares = [].reduce(shuffle, []).map(n => n*n);

让我们将shuffle定义为:

var shuffle = (rand, one, i, orig) => {
  if (i !== 1) return rand;  // Randomize it only once (arr.length > 1)

  // You could use here other random algorithm if you wanted
  for (let i = orig.length; i; i--) {
    let j = Math.floor(Math.random() * i);
    [orig[i - 1], orig[j]] = [orig[j], orig[i - 1]];
  }

  return orig;
}

您可以在JSFiddle或此处看到它的实际应用:

var shuffle=(all,one,i,orig)=>{如果(i!==1)返回全部;//你可以在这里使用其他随机算法for(设i=原始长度;i;i-){设j=数学地板(Math.random()*i);[原始[i-1],原始[j]]=[原始[j],原始[i-1]];}返回原点;}对于(变量i=0;i<5;i++){var randomarray=[1,2,3,4,5,6,7]。reduce(shuffle,[]);console.log(JSON.stringify(randomarray));}

首先,在这里查看javascript中不同排序方法的视觉比较。

其次,如果您快速查看上面的链接,您会发现与其他方法相比,随机顺序排序的性能似乎相对较好,同时实现起来非常简单和快速,如下所示:

function shuffle(array) {
  var random = array.map(Math.random);
  array.sort(function(a, b) {
    return random[array.indexOf(a)] - random[array.indexOf(b)];
  });
}

编辑:正如@gregers所指出的,比较函数是用值而不是索引来调用的,这就是为什么需要使用indexOf的原因。注意,由于indexOf在O(n)时间内运行,此更改使代码不太适合较大的数组。

$=(m)=>控制台日志(m);//----将此方法添加到Array类Array.prototype.shuffle=函数(){return this.sort(()=>.5-Math.random());};$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());