Samuel
Samuel

Reputation: 18586

Puts ruby hash in random order

I wrote a code that matches every letter from an alphabet with another character (string with length 1) and i turned the two into a hash:

Hash[String.alphabet.zip String.alphabet]
# String.alphabet returns an array with 0:A, 1:B, ... ,25:Z
# I take two times the alphabet to demonstrate

But when i print the hash with

puts "#{hash.keys.join}\n#{hash.values.join}"

it gives me

VKWLAXMBYNCZODPEQFRGSHTIUJ
VKWLAXMBYNCZODPEQFRGSHTIUJ

, which - while being correct - is hard to read if i wanna see if letters are matched correctly, i'd much prefer an output in the form of

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ

[The print method works correctly on other hashes and is by my knowledge correct]

So: How can i 'zip' the arrays while keeping the original order of keys?

Upvotes: 1

Views: 1262

Answers (3)

Ken Bloom
Ken Bloom

Reputation: 58790

It's not the zip, it's the Hash that's the problem.

A hash table ordinarly (in the general world of computer science) doesn't keep track of the order that data's inserted (or any other sort order) all it wants to know about is lookup. If you want to traverse a hash table to see everything that's in it, you end up traversing the elements in order of the buckets where the elements are stored. That's typically some modulo of the hash function. With a good hash function, that's essentially a random order.

In Ruby 1.8, that's how hash tables are implemented.

Realizing that people expect their Hashes to remember the order of elements, the Ruby developers added some kind of linked list to their hash tables in Ruby 1.9, so that you could traverse the elements in a non-random order.

Upvotes: 1

glenn mcdonald
glenn mcdonald

Reputation: 15488

The answers about ordered hashes are correct, but in your case you don't necessarily have to keep the hash in order, you can just sort it for your output.

puts hash.sort.transpose.map(&:join)

Upvotes: 3

fl00r
fl00r

Reputation: 83680

Sorted hashes you can use in Ruby 1.9.x. In Ruby 1.8.7 Hashes are unsorded

From API:

A Hash is a collection of key-value pairs. It is similar to an Array, except that indexing is done via arbitrary keys of any object type, not an integer index. The order in which you traverse a hash by either key or value may seem arbitrary, and will generally not be in the insertion order.

Upvotes: 3

Related Questions