2012-06-11 8 views

Respuesta

25

¿Qué tal esto:

array.delete_at(rand(array.length)) 
+0

Esto es esencialmente dos steps ('rand (array.length)' y 'array.delete_at (idx)'). OP solo solicitó un método, pero probablemente una de las formas más simples de realizar este tipo de operación en Ruby. – sindrenm

2

Linuxios es lo tiene perfecto. Este es otro ejemplo:

array = %w[A B C] 
item_deleted = array.delete_at(1) 

Aquí está en IRB:

1.9.2p0 :043 > array = %w[A B C] 
=> ["A", "B", "C"] 
1.9.2p0 :044 > item_deleted = array.delete_at(1) 
=> "B" 
1.9.2p0 :045 > array 
=> ["A", "C"] 
1.9.2p0 :047 > item_deleted 
=> "B" 
+1

Gracias por los ejemplos adicionales. – Linuxios

1

Una alternativa al enfoque rand (Array.length) ya se ha mencionado, podría ser éste

element = array.delete array.sample 

Ejemplo de ejemplo:

>> array = (1..10).to_a 
>> element = array.delete array.sample 
>> array # => [1, 2, 4, 5, 6, 7, 8, 9, 10] 
>> element # => 3 

This también es un conjunto de dos operaciones, pero al menos no tendrá que alejarse de la matriz en sí.

+1

Éste puede ser menos eficiente que los otros (eliminar requiere una búsqueda) pero es obvio de un vistazo lo que está haciendo. – micapam

+0

Esto es cierto, pero creo que es un poco más legible que usar 'rand', ya que hay una manera de encontrar un elemento aleatorio en una matriz. Además, no tenemos que arrastrar la longitud de la matriz, que es algo que realmente no deberíamos tener en cuenta. :-) – sindrenm

+0

Sí - por 'obvio' me refiero a legible :) – micapam

11

Otro ineficiente, pero super obvio lo que está pasando:

array.shuffle.pop 

Lo que estaría bien sería una versión destructiva del método de la muestra en la matriz en sí, algo así como:

class Array 
    def sample! 
    delete_at rand length 
    end 
end 
+3

Conclusión: algo así como su segundo ejemplo (aunque en el idioma en el que se implementa el intérprete) debe ser parte de la implementación central de Array. ¡Probablemente lo llamaría algo así como 'delete_sample!' O algo así, ya que me parece un poco más obvio lo que hace. :-) – sindrenm

+1

Tiene que ser array.shuffle! .pop – seo

+3

Si elige esta opción y desea eliminar el elemento de la matriz original, mejor haga 'array.shuffle! .pop', de lo contrario, su matriz se mantendrá como era. Hacer 'shuffle' sin bang (!) Simplemente te dará otra matriz para' pop'. – mjnissim

0

Si necesita muestrear una cantidad de elementos y eliminarlos del conjunto original:

array = (1..10).to_a 

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

grab = array.sample(4) 

=> [2, 6, 10, 5] 

grab.each{ |a| array.delete a } 

=> [2, 6, 10, 5] 

array 
=> [1, 3, 4, 7, 8, 9] 
+1

Esto solo funciona si su matriz original está llena de valores únicos; de lo contrario, estaría borrando todos los '2' – Anthony

Cuestiones relacionadas