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);
}
これでまあまあランダムに並び替えてくれるので、ライトな使い方では十分でしょう。