JavaScript
sort

超大雑把に配列の順序をランダムにする方法 (非破壊編集)

JavaScriptでランダムに配列をソートしたい、だけどもとの配列に影響を与えたくないということで考えたものです。

Fisher-Yates というアルゴリズムを見かけたのですが、もとの配列を並び替えるし状態管理の変数を使うというものだったのでスルーです。


@hogefuga さんのコメントより

非破壊なFisher-Yatesを教えていただきました。

const randomSort = array =>
   array.reduce((sorted, value, i) => {
      const j = Math.floor(Math.random() * i);
      if (j === i) {
         return [...sorted, value];
      }
      else {
         return [...sorted.slice(0, j), value, ...sorted.slice(j)];
      }
   }, []);

同じコメントでPrototypeの拡張はアカンということも教えていただきました。

ありがとうございます!


最終的なコードは下記の通り。

const randomSort = srcArray => {
  const newArray = Array(srcArray.length);
  srcArray.map(value => {
    const key = Math.floor(Math.random() * (srcArray.length + 1));
    newArray.splice(key, 0, value);
  })

  return newArray.filter(value => value);
}

Array オブジェクトのメソッドとして。(←アカンやつです)

Array.prototype.randomSort = function() {
 const newArray = Array(this.length);
 this.map((value) => {
    newArray.splice(Math.floor(Math.random() * (this.length + 1)), 0, value);
 });

 return newArray.filter(value => value);
}

これでまあまあランダムに並び替えてくれるので、ライトな使い方では十分でしょう。