2012-05-18 6 views
8

Ich benutze das folgende Stück Code, um meine Textdatei in einen Hashset zu laden.Get random Element von hashset?

HashSet<string> hashs = new HashSet<string>(File.ReadLines("textFile.txt")); 

Ich frage mich, ob es eine einfache Möglichkeit gibt, eine zufällige Zeile daraus zu bekommen?

Lässt asume die TextFile.txt enthält 10 Zeilen, ich möchte randomize und greifen Sie eine dieser vorhandenen Zeilen.

+1

Was hast du probiert? Haben Sie versucht, die System.Random-Klasse zu verwenden, um eine Zufallszahl zwischen 0 und <# of lines> zu generieren und dann dieses Element nach Index zu referenzieren? Dies sind alle Aufgaben, die bereits in der MSDN-Bibliothek dokumentiert sind. http://mattgememm.com/2008/12/08/what-have-you-tried/ – David

Antwort

10
Random randomizer = new Random(); 
string[] asArray = hashs.ToArray() 
string randomLine = asArray[randomizer.Next(asArray.length)]; 
+0

funktioniert perfekt! danke Mann – user1213488

+3

Ziemlich ineffiziente Leistung. Nicht dass ich einen besseren Weg kenne, sondern nur sagen. – batman

2

Sie können eine Zufallszahl zwischen 0 und der Größe des Satzes generieren und dann die Einrichtung durchlaufen, bis Sie das Element erreichen, dessen Index mit der generierten Zahl übereinstimmt. Dann wählen Sie dieses Produkt als Zufallselement

+0

Wie würde der Code dafür aussehen? nicht sicher, wie man das schreibt :) – user1213488

+0

1. Google "System.Random". 2. Sehen Sie sich die bereits bereitgestellten Dokumentationen und Codebeispiele im Internet an. 3. Lernen Sie, anstatt eine Copy/Paste-Antwort zu verwenden. (Ich denke, heute ist einer meiner "Jerk" -Tage.) – David

1

Oder vielleicht eine allgemeinere Lösung für jede zählbare

public static class RandomExtensions 
{ 
    private static readonly Random rnd = new Random(); 
    private static readonly object sync = new object(); 

    public static T RandomElement<T>(this IEnumerable<T> enumerable) { 
     if (enumerable == null) 
      throw new ArgumentNullException("enumerable"); 

     var count = enumerable.Count(); 

     var ndx = 0; 
     lock (sync) 
      ndx = rnd.Next(count); // returns non-negative number less than max 

     return enumerable.ElementAt(ndx); 
    } 
} 
+0

'ElementAt' wird Ausnahme für leere Sammlung werfen. –

+2

@lazyberezovsky Wenn ElementAt löst, sollte als RandomElement auch die gleiche Ausnahme auslösen. Es sollte ein RandomElementOrDefault in diesem Fall sein – Vasea

24

eine einfache Antwort, wie die Sicherheiten akzeptiert, ist möglich, ohne dass das gesamte Array Aufzählen jedes Mal: ​​

private static readonly Random  random = new Random(); 
private static readonly HashSet<T> hashset = new HashSet<T>(); 

... 

T element = hashset.ElementAt(random.Next(hashset.Count)); 
+6

ElementAt zählt Elemente immer noch auf, bis es den angegebenen Index erreicht. Es wird also nicht schneller. – Zonko