コレクション(配列など)のシャッフル

ref: ランダムソート(笑)とは - 西尾泰和のはてなダイアリー
ref: 単純で正しそうなものが正しいとは限らない - Radium Software

ネット上で、配列などのシャッフルについて検索すると、ソートの比較関数に乱数生成機を渡すとか書いてあるのが多いのでなんかどうでも良くなっていたのだが、それについて丁寧に言及しているページ(リンク先)を見つけたので weblog

一番目のリンク先の内容はともかく、二番目のやつについてはうっかりやってしまいかねないので気をつけないと。

ちなみに、そもそもコレクションのシャッフルについて調べたのは、そのためのユーティリティを SUtlis に置いておいて、何回も書かないで良くしようと思ったため。

なお、上記の二番目のリンク先の内容を元に、IEnumerable を偏りのなくシャッフル(Knuth-Fisher-Yates shuffle algorithm)する拡張メソッドを、C# で書くと以下のようになる。

public static T[] Shuffle<T>(this IEnumerable<T> src, Random rand) {
	if (rand == null) rand = new Random();

	var result = src.ToArray();
	for (int i = result.Length - 1; i >= 1; i--) {
		var n = rand.Next(i + 1);

		var item = result[i];
		result[i] = result[n];
		result[n] = item;
	}
	return result;
}