Random entry from dictionary

What is the best way to get a random entry from a Dictionary in c#?

I need to get a number of random objects from the dictionary to display on a page, however I cannot use the following as dictionaries cannot be accessed by index:

Random rand = new Random();
Dictionary< string, object> dict = GetDictionary();
return dict[rand.Next()];

Any suggestions?


Solution 1:

If you're using .net 3.5, Enumerable has an extension method ElementAt which would allow you to do:

return dict.ElementAt(rand.Next(0, dict.Count)).Value;

Solution 2:

Updated to use generics, be even faster, and with an explanation of why this option is faster.

This answer is similar to the other responses, but since you said you need "a number of random elements" this will be more performant:

public IEnumerable<TValue> RandomValues<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
    Random rand = new Random();
    List<TValue> values = Enumerable.ToList(dict.Values);
    int size = dict.Count;
    while(true)
    {
        yield return values[rand.Next(size)];
    }
}

You can use this method like so:

Dictionary<string, object> dict = GetDictionary();
foreach (object value in RandomValues(dict).Take(10))
{
    Console.WriteLine(value);
}

This has performance improvements over the other responses (including yshuditelu's response).

  1. It doesn't have to create a new collection of all of the dictionary's elements each time you want to fetch a new random value. This is a really big deal if your dictionary has a lot of elements in it.
  2. It doesn't have to perform a lookup based on the Dictionary's key each time you fetch a random value. Not as big a deal as #1, but it's still over twice as fast this way.

My tests show that with 1000 objects in the dictionary, this method goes about 70 times faster than the other suggested methods.