2012-05-18 15 views
8

Im utilizzando il seguente pezzo di codice per caricare il mio file di testo in un hashset .Ottieni elementi casuali da hashset?

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

Mi chiedo se c'è un modo semplice per ottenere una linea a caso da esso?

Consente il file textFile.txt contiene 10 righe, mi piacerebbe randomizzare e prendere una di quelle linee esistenti.

+1

Cosa hai provato? Hai provato a utilizzare la classe System.Random per generare un numero casuale compreso tra 0 e <# of lines> e quindi fare riferimento a quell'elemento per indice? Queste sono tutte attività già documentate nella libreria MSDN. http://mattgemmell.com/2008/12/08/what-have-you-tried/ – David

risposta

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

funziona perfettamente! grazie uomo – user1213488

+3

Prestazioni abbastanza inefficienti. Non che io conosca un modo migliore, ma solo dicendo. – batman

2

È possibile generare un numero casuale compreso tra 0 e la dimensione del set, quindi scorrere l'impostazione fino a raggiungere l'elemento il cui indice è uguale al numero generato. Quindi selezionare questo articolo come l'elemento casuale

+0

come sarebbe il codice per quello sguardo? non so come scriverlo :) – user1213488

+0

1. Google "System.Random". 2. Guarda gli esempi di documenti e codici già disponibili disponibili su tutto il web. 3. Impara, piuttosto che usare una risposta di copia/incolla. (Immagino che oggi sia uno dei miei giorni da "coglione".) – David

1

O forse una soluzione più generale per qualsiasi enumerabile

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' genererà un'eccezione per la raccolta vuota. –

+2

@lazyberezovsky Se ElementAt lancia, anche RandomElement dovrebbe lanciare la stessa eccezione. Ci dovrebbe essere un RandomElementOrDefault in questo caso – Vasea

24

una risposta semplice, come quella accettata è possibile senza enumerare l'intero array ogni volta:

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 continua a enumerare gli elementi fino a raggiungere l'indice specificato, quindi non sarà incredibilmente più veloce. – Zonko

Problemi correlati