2012-02-06 9 views
7

Perché (identità di gruppo (intervallo 1 50)) restituisce risultati comePerché il gruppo di clojure non sempre mantiene l'ordine?

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

Si tratta di multi-threading? C'è un modo per aggirarlo?

... e si rompe è il contratto?

Restituisce una mappa degli elementi di coll codificati dal risultato di f su ciascun elemento. Il valore di ciascun tasto sarà un vettore degli elementi corrispondenti, nell'ordine in cui sono stati visualizzati in coll.

risposta

14

Provare a inserire (type (group-by identity (range 1 50))) nel REPL. Puoi vedere che il risultato è in realtà una mappa hash (della classe clojure.lang.PersistentHashMap). Ciò significa che non è ordinato: in linea di principio, il REPL potrebbe emettere la mappa stampata in qualsiasi ordine di coppie chiave/valore.

Il motivo reale per cui viene stampato il modo in cui è stampato ha a che fare con l'implementazione di una mappa hash di Clojure: in termini di strutture dati, è in realtà un ampio albero in cui ogni nodo può avere fino a 32 figli (da qui l'iniziale 32 nella tua produzione, ricorda che i vettori e le mappe Clojure sono spesso citati per avere un costo di ricerca di O (log32N)). This blog article ha un buon sommario.

E no, non viola il contratto di group-by. Il contratto specifica solo l'ordine degli elementi dei valori della mappa, non l'ordinamento della mappa di per sé.

+0

La parte "il valore di ciascun tasto" sembra così ovvia ora! ;) E mi stavo chiedendo anche il 32, ma ho pensato che ci fossero abbastanza Qs lì dentro. Grazie. – status203

Problemi correlati