Gul*_*han 23 c# ienumerable shuffle
我需要一个可以随机播放的扩展方法IEnumerable<T>.它还可以int指定返回的大小IEnumerable.更好地保持不变性IEnumerable.我目前的解决方案IList-
public static IList<T> Shuffle<T>(this IList<T> list, int size)
{
Random rnd = new Random();
var res = new T[size];
res[0] = list[0];
for (int i = 1; i < size; i++)
{
int j = rnd.Next(i);
res[i] = res[j];
res[j] = list[i];
}
return res;
}
public static IList<T> Shuffle<T>(this IList<T> list)
{ return list.Shuffle(list.Count); }
Run Code Online (Sandbox Code Playgroud)
Luk*_*keH 46
你可以使用Fisher-Yates-Durstenfeld shuffle.没有必要将size参数显式传递给方法本身,Take如果不需要整个序列,可以简单地调用一个调用:
var shuffled = originalSequence.Shuffle().Take(5);
// ...
public static class EnumerableExtensions
{
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
return source.Shuffle(new Random());
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
if (source == null) throw new ArgumentNullException("source");
if (rng == null) throw new ArgumentNullException("rng");
return source.ShuffleIterator(rng);
}
private static IEnumerable<T> ShuffleIterator<T>(
this IEnumerable<T> source, Random rng)
{
var buffer = source.ToList();
for (int i = 0; i < buffer.Count; i++)
{
int j = rng.Next(i, buffer.Count);
yield return buffer[j];
buffer[j] = buffer[i];
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11914 次 |
| 最近记录: |