¿Cómo puedo generar una lista de n números aleatorios únicos en Ruby?

Esto es lo que tengo hasta ahora:

myArray.map!{ rand(max) } 

Obviamente, sin embargo, a veces los números en la lista no son únicos. ¿Cómo puedo asegurarme de que mi lista solo contenga números únicos sin tener que crear una lista más grande de la cual simplemente elijo los n números únicos?

Editar:
Realmente me gustaría ver esto hecho sin ciclo, si es posible.

    Esto usa Set:

     require 'set' def rand_n(n, max) randoms = Set.new loop do randoms < < rand(max) return randoms.to_a if randoms.size >= n end end 
     (0..50).to_a.sort{ rand() - 0.5 }[0..x] 

    (0..50).to_a se puede reemplazar con cualquier matriz. 0 es “valor mínimo”, 50 es “valor máximo” x es “cuántos valores deseo”

    por supuesto, es imposible que x sea mayor que max-min 🙂

    En expansión de cómo funciona esto

     (0..5).to_a ==> [0,1,2,3,4,5] [0,1,2,3,4,5].sort{ -1 } ==> [0, 1, 2, 4, 3, 5] # constant [0,1,2,3,4,5].sort{ 1 } ==> [5, 3, 0, 4, 2, 1] # constant [0,1,2,3,4,5].sort{ rand() - 0.5 } ==> [1, 5, 0, 3, 4, 2 ] # random [1, 5, 0, 3, 4, 2 ][ 0..2 ] ==> [1, 5, 0 ] 

    Notas al pie:

    Vale la pena mencionar que en el momento en que se respondió originalmente esta pregunta, en septiembre de 2008, ese Array#shuffle o no estaba disponible o no estaba ya disponible para mí, de ahí la aproximación en Array#sort

    Y como resultado, hay un aluvión de ediciones sugeridas.

    Asi que:

     .sort{ rand() - 0.5 } 

    Puede ser mejor y más breve en las implementaciones de ruby ​​modernas que usan

     .shuffle 

    Adicionalmente,

     [0..x] 

    Puede escribirse más obviamente con Array#take as:

     .take(x) 

    Por lo tanto, la manera más fácil de producir una secuencia de números aleatorios en un Ruby moderno es:

     (0..50).to_a.shuffle.take(x) 

    Solo para darle una idea sobre la velocidad, ejecuté cuatro versiones de esto:

    1. Usando Sets, como la sugerencia de Ryan.
    2. Usando una matriz un poco más grande de lo necesario, ¡entonces haciendo uniq! al final.
    3. Usando un Hash, como sugirió Kyle.
    4. Creando una Matriz del tamaño requerido, luego ordenándola al azar, como la sugerencia de Kent (pero sin el extraño “- 0.5”, que no hace nada).

    Todos son rápidos a pequeña escala, así que los hice crear una lista de 1,000,000 de números. Estos son los tiempos, en segundos:

    1. Conjuntos: 628
    2. Array + uniq: 629
    3. Hash: 645
    4. Arreglo fijo + ordenación: 8

    Y no, ese último no es un error tipográfico. Entonces, si te preocupa la velocidad, y está bien que los números sean enteros de 0 a lo que sea, entonces mi código exacto fue:

     a = (0...1000000).sort_by{rand}