2011-07-05 8 views
7

estoy haciendo algo como esto con una lista 'A':¿Está garantizado que el iterador .each en ruby ​​siempre da el mismo orden en los mismos elementos cada vez?

a.each_with_index |outer, i| 
    a.each_with_index |inner, j| 
    if(j > i) 
     # do some operation with outer and inner 
    end 
    end 
end 

si el iterador no va a utilizar el mismo fin, esto no va a funcionar. No me importa qué es realmente el pedido, solo necesito dos iteradores .each_with_index para usar el mismo orden.

yo asumiría que sería una propiedad de una matriz que tiene un orden fijo y sólo estoy siendo paranoico que el iterador no usaría ese orden ...

+0

Cuando dices "lista", ¿te refieres a "matriz", o también podrías querer decir "establecer"? –

+0

En este caso, es una matriz. Aunque también tengo algunos sets. Supongo que me preguntaba si cada uno implicaría una orden, pero tiene más sentido suponer que solo una colección ordenada estaría en orden ... –

Respuesta

15

Esto depende del objeto específico Enumerable en el que está operando.

Las matrices, por ejemplo, siempre devolverán elementos en el mismo orden. Pero no se garantiza que otros objetos enumerables se comporten de esta manera. Un buen ejemplo de esto es el Hash de 1.8.7 base. Es por eso que muchos frameworks (más notablemente ActiveSupport) implementan un OrderedHash.

Una nota al margen interesante: incluso Hash devolverá objetos en el mismo orden si el hash no ha cambiado entre each llamadas. Si bien muchos objetos se comportan de esta manera, confiar en esta sutileza probablemente no sea una gran idea.

Entonces, no. El genérico each no siempre devolverá los objetos en el mismo orden.

P.S. Los hashes de Ruby 1.9 ahora están ordenados http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash

6

yo no he mirado en su código actual, pero aquí está su respuesta tomada de Ruby API docs:

Las matrices son ordenadas, colecciones de índices enteros de cualquier objeto.

Así que sí, estás siendo paranoico, pero seguramente eso es algo bueno cuando estás desarrollando?

+0

De acuerdo. http://www.ruby-doc.org/core/classes/Array.html –

+2

Supongo que mi preocupación es que el iterador podría (¿por alguna razón?) cambiar el orden ... –

2

Por definición, la matriz es una lista ordenada de elementos. Entonces no deberías tener problemas con eso.

1

Depende del Enumerable específico. Ciertamente, una matriz siempre se repetirá en el orden obvio.

Sería una franja bastante lunática para alguien implementar un método each que atravesaría la misma colección de diferentes maneras, pero la única restricción real para dicha "característica" estaría en la documentación de la clase que se mezcla en Enumerable . Bueno, en eso y la cordura de los implementadores.

Casi puedo imaginar algún tipo de API criptográfica que atraviesa deliberadamente una colección de una manera impredecible.

+0

He implementado .each_random en alguna ocasión. .. –

+0

Heh, awesome ... – DigitalRoss

+0

También para pruebas estadísticas es útil atravesar aleatoriamente enumerables ... – hildensia

Cuestiones relacionadas