“Shuffle” an IEnumerable

By | November 13, 2012

Working on a current project, had a need to do this. It’s a pretty brute-force way of doing things because frankly, I’m not a brainiac :)

Interested in what my readers think.

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> collection)
		{
			var r = new Random();
			var enumerable = collection as T[] ?? collection.ToArray();
			int numItems = enumerable.Count();
			// Create a new spot to put 'em
			var retVal = new T[numItems];

			// Know which ones we've put in
			var addedIndices = new int[numItems];

			for (int i = 0; i < numItems; i++)
			{
				if (i == numItems - 1)
				{   // Last item, don't waste any time just pick the last one available
					retVal[i] = enumerable.Except(retVal).First();
				}
				else
				{
					// Pick one from the source that we haven't picked yet
					int chosenIndex;
					do
					{
						chosenIndex = r.Next(numItems);
					} while (addedIndices.Contains(chosenIndex));

					retVal[i] = enumerable[chosenIndex];
					addedIndices[i] = chosenIndex;
				}
			}

			return retVal;
		}