I need an extension method which will shuffle an IEnumerable<T>
. It can also take an int
to specify the size of the returned IEnumerable
. Better keeping Immutability of the IEnumerable
. My current solution for 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); }
With some LINQ love:
Anton's got the idea, but you could make it a two-liner:
Unfortunately, it can't be lazily evaluated because
r
will be out of scope when it does execute. You can create an IEnumerable implementation that encapsulates this code and return that, but that gets more complex.You can use a Fisher-Yates-Durstenfeld shuffle. There's no need to explicitly pass a size argument to the method itself, you can simply tack on a call to
Take
if you don't need the entire sequence: