views:

137

answers:

5

What's the fastest way to get a random value from a string array in C# on the .net 2.0 framework? I figured they might have had this:

string[] fileLines = File.ReadAllLines(filePath);
fileLines.GetRandomValue();

Yes, I know GetRandomValue() is not an actual method, is there something similar that's more or less equally short and sweet?

+1  A: 

Indeed.

Random m = new Random();
string line = fileLines[m.Next(0, fileLines.Length);
Noon Silk
+1, this also works.
Mr. Smith
+1  A: 

Try:

fileLines [new Random ().Next (fileLines.Length)]

Skizz

Skizz
+1, for a one-liner.
Mr. Smith
Calling this multiple times in quick succession (for example, in a tight loop) will return the same line every time.
LukeH
+8  A: 

Not built in, but easy enough to add...

static readonly Random rand = new Random();
public static T GetRandomValue<T>(T[] values) {
    lock(rand) {
        return values[rand.Next(values.Length)];
    }
}

(the static field helps ensure we don't get repeats if we use it in a tight loop, and the lock keeps it safe from multiple callers)

In C# 3.0, this could be an extension method:

public static T GetRandomValue<T>(this T[] values) {...}

Then you could use it exactly as per your example:

string[] fileLines = File.ReadAllLines(filePath);
string val = fileLines.GetRandomValue();
Marc Gravell
Another way to do it is to make rand [ThreadStatic] and use a seed that is derived from system time and ThreadID, and avoid locking altogether ...
Pop Catalin
Thanks Marc, perfect!
Mr. Smith
Personally, I think it's a bit of an abuse of extension methods to add this as one. It's clearly not required for all string[] arrays within the application.
Noon Silk
I only said "could", to illustrate the usage from the OPs question, and extension methods have no cumulative cost on code performance. The container class could be in a "Utils.Arrays" namespace, for example, tightly limiting scope.
Marc Gravell
I know; but I just think it's a classic example of why extension methods are bad : it's too easy to add useless ones to solve specific problems, rather than adding new general functionality for the benefit or your entire app.
Noon Silk
A: 

I guess you want to calculate some kind of hash value?

See: http://stackoverflow.com/questions/1388702/c-md5-calculation-issue

Philippe Leybaert
+1  A: 

I don't think arrays support such a function. The easiest way is just to get a random number, and get the corresponding item.

Random rnd = new Random();
String item = fileLines[rnd.next(fileLines.Length);
Ikke
+1, this works too.
Mr. Smith