Do hash-key and hash-values give their results in the same order?
When working with hash tables in Racket, two useful functions are
hash-values. The first returns all the keys used in the hash table, as a list. The second returns, analogously, the values. Nothing terribly surprising there.
When we need to work, separately, with the keys and the values of a hash table, an interesting question presents itself:
Is it safe to assume that the list that
hash-keys returns has the same order as the list returned by
Is, for instance, the first element of the list returned by
hash-values the hash value of the first element returned by
hash-keys? To put the question in terms of code: is it true, for a hash table
(equal? (list-ref (hash-values h) 0) (hash-ref h (list-ref (hash-keys h) 0)))
and so forth, for 1, 2, etc.?
The answer is: No, that is not necessarily true.
If, in some cases, it is true, that’s accidental and not something to rely upon. The documentation for both functions says that the results are provided
in an unspecified order.
Think of it this way. When using
hash-values, you’re losing information. Applying these functions deliberately cuts the tie between the key and values of a hash.
hash-key gives just a list of keys; it makes no promises about the order of its results. And similarly for
Here’s how you can convince yourself of this. Run the following code in DrRacket:
#lang racket (define h (make-hash '(("a" . 0) ("b" . -1) ("c" . 4)))) (hash-keys h) ;; ("c" "a" "b") (hash-values h) ;; (-1 0 4), 'wrong' order
These results show that you can’t really rely on the order. If you get results that don’t contradict the conjecture, consider yourself lucky.