2012-02-06 4 views
7

¿Por qué (grupo por identidad (rango 1 50)) devuelve resultados como¿Por qué el grupo de clojure no siempre mantiene el orden?

{32 [32], 1 [1], 33 [33], 2 [2], 34 [34], 3 [ 3], 35 [35] ...

¿Está relacionado con varios subprocesos? ¿Hay alguna manera de evitarlo?

... ¿y rompe su contrato?

Devuelve un mapa de los elementos de coll tecleados por el resultado de f en cada elemento. El valor en cada tecla será un vector de los elementos correspondientes, en el orden en que aparecieron en coll.

Respuesta

14

Intenta ingresar (type (group-by identity (range 1 50))) en tu REPL. Puede ver que el resultado es en realidad un mapa hash (de la clase clojure.lang.PersistentHashMap). Esto significa que no está ordenado: en principio, el REPL podría generar el literal del mapa impreso en cualquier orden de pares clave/valor. El verdadero motivo por el que se imprimió tal como está impreso tiene que ver con la implementación de un mapa hash de Clojure. En términos de estructuras de datos, en realidad es un árbol ancho donde cada nodo puede tener hasta 32 hijos (de ahí 32 en su salida; recuerde que los vectores y mapas Clojure a menudo se citan para tener un costo de búsqueda de O (log32N)). This blog article tiene un buen resumen.

Y no, no infringe el contrato de group-by. El contrato solo especifica el orden de los elementos de los valores del mapa, no el orden del mapa per se.

+0

La parte "el valor en cada tecla" parece tan obvia ahora! ;) Y me preguntaba acerca de los 32 también, pero pensé que había suficientes Qs allí. Gracias. – status203

Cuestiones relacionadas