LINQでIEからランダムに要素を取り出す を見ていて、IEnumerableを2回パスするのは嫌だなあと感じたので、ワンパスバージョンを作成しました。
using System;
using System.Collections.Generic;
public static class EnumeratorEx {
private static readonly Random rand = new Random();
public static T Random<T>(this IEnumerable<T> arg) {
T selected = default(T);
var n = 0;
foreach (var item in arg) {
n += 1;
if (rand.Next(n) == 0) {
selected = item;
}
}
return selected;
}
}
public class Test {
public static void Main() {
var items = new[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
for (int i = 0; i < 100; i++) {
Console.Write(items.Random() + ", ");
}
}
}
1~0まで全部表示されるので、大丈夫そうです。
あと、パフォーマンスは計測していません。