2012-05-18 20 views
8

Im utilizando la siguiente pieza de código para cargar mi archivo de texto en un hashset.Obtener elemento aleatorio de hashset?

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

¿Me pregunto si hay alguna manera fácil de obtener una línea al azar de ella?

Permite asume que textFile.txt contiene 10 líneas, me gustaría aleatorizar y tomar una de esas líneas existentes.

+1

¿Qué has probado? ¿Ha intentado utilizar la clase System.Random para generar un número aleatorio entre 0 y <# of lines> y luego hacer referencia a ese elemento por índice? Esas son todas las tareas ya documentadas en la biblioteca de MSDN. http://mattgemmell.com/2008/12/08/what-have-you-tried/ – David

Respuesta

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

funciona perfectamente! gracias hombre – user1213488

+3

bastante ineficiente rendimiento sabio. No es que conozca una mejor manera, solo que decir. – batman

2

Puede generar un número aleatorio entre 0 y el tamaño del conjunto, luego iterar a través de la configuración hasta llegar al elemento cuyo índice es el mismo que el número generado. A continuación, seleccione este elemento como el elemento aleatorio

+0

¿cómo sería el código para ese aspecto? no estoy seguro de cómo escribir eso :) – user1213488

+0

1. Google "System.Random". 2. Mire las muestras de código y documentación ya provistas disponibles en toda la web. 3. Aprender, en lugar de usar una respuesta copiar/pegar. (Creo que hoy es uno de mis días "idiotas") – David

1

O tal vez una solución más general para cualquier enumerables

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' arrojará una excepción para la colección vacía. –

+2

@lazyberezovsky Si ElementAt arroja, entonces RandomElement también debería arrojar la misma excepción. ¡Debería haber un RandomElementOrDefault en este caso – Vasea

24

una respuesta simple como el aceptado es posible sin la enumeración de toda la matriz en cada ocasión:

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

ElementoAún enumera elementos hasta que alcanza el índice especificado, por lo que no será mucho más rápido. – Zonko

Cuestiones relacionadas