2012-06-11 8 views
5

Supongamos que tengo un objeto enumerable enum y ahora quiero obtener el tercer elemento.consulte un valor de enumerador con índice especificado

Sé que uno de un enfoque general es convertir en una matriz y luego acceder con índice como:

enum.to_a[2] 

Pero de esta manera se creará una matriz temporal, que puede ser ineficiente.

Ahora uso:

enum.each_with_index {|v, i| break v if i == 2} 

Pero esto es bastante feo y redundante.

¿Cuál es la forma más eficiente de hacer esto?

Respuesta

5

Usted podría utilizar take de pelar los tres primeros elementos y luego last para agarrar el tercer elemento de la matriz que le da take:

third = enum.take(3).last 

Si no desea generar las matrices en absoluto entonces tal vez:

# If enum isn't an Enumerator then 'enum = enum.to_enum' or 'enum = enum.each' 
# to make it one. 
(3 - 1).times { enum.next } 
third = enum.next 
+0

Esto se ve mejor, pero, si quiero un número muy grande como índice, que todavía va a generar una matriz temporal muy grande para él. –

+0

@ShouYa: agregué otra opción sin arreglos mientras estaba comentando. Todavía tienes que marcar 'enum' uno por uno, pero no hay nada que puedas hacer al respecto (en general). –

+0

Usar siguiente es una sugerencia inteligente. Sentiría curiosidad por ver cuáles son las implicaciones del rendimiento en comparación con convertir una colección en una matriz. –

1

Desafortunadamente, para acceder a un miembro por el índice tiene que ser convertido a una matriz (de lo contrario no tendría un índice en el primer lugar), por lo que su código se ve perfectamente bien para mí.

+0

Um, no. Si 'e' es un' Enumerador', '2.times {e.next}' marcará y arrojará los primeros dos valores y un tercero 'e.next' le dará el tercero sin generar ninguna matriz. –

+0

@muistooshort sip, respondí a tu hilo. Y tienes razón en ese aspecto. –

5

Alternativa a la respuesta de mu utilizando enumerable-lazy o Ruby 2.1. Tan vago como el uso de next pero mucho más declarativa:

enum.lazy.drop(2).first 
Cuestiones relacionadas