Hash.keys Q 
Author Message
 Hash.keys Q

Hi all

I have written my first ruby program, and it was fun, but there is one
litle detail i'm wondering about.
The program logs on/off to my isp via a slightly modified telnet
function. The options for "telnet" is a hash read from a file.

File.foreach(conffile){ |l| options[$1]= $2 if l ~= /(.*):\s+(.*)/ }
the conffile looks like this:

Host: IP-addr.
Port: portnr.
Name: username
Password: password

Now options.keys returns ["Password", "Host", "Port", "Name"]

I would expect ["Host", "Port", "Name", "Password"]

is there an explanation for this ?

The program is about 70 lines, so i could post it in case it is me doing
something stupid. (very likely :-) )

Leo
ruby -v: ruby 1.6.5 (2001-11-28) [i386-linux]
--
Aphasia:
        Loss of speech in social scientists when asked
        at parties, "But of what use is your research?"



Sat, 29 May 2004 22:58:29 GMT  
 Hash.keys Q
Hello --

Quote:

> Hi all

> I have written my first ruby program, and it was fun, but there is one
> litle detail i'm wondering about.

Welcome to Ruby!

Quote:
> The program logs on/off to my isp via a slightly modified telnet
> function. The options for "telnet" is a hash read from a file.

> File.foreach(conffile){ |l| options[$1]= $2 if l ~= /(.*):\s+(.*)/ }
> the conffile looks like this:

> Host: IP-addr.
> Port: portnr.
> Name: username
> Password: password

> Now options.keys returns ["Password", "Host", "Port", "Name"]

> I would expect ["Host", "Port", "Name", "Password"]

> is there an explanation for this ?

Yes: the order of hash keys is not guaranteed.  I *think* #keys
returns the keys in the same order when called multiple times, but I'm
not 100% sure.  In any case, that order itself cannot be predicted.

I believe various people have written various OrderedHash
extensions... (very helpful advice, I know :-) You could search on
<http://www.ruby-talk.org> to see if there's been discussion here.

David

--
David Alan Black


Web:  http://pirate.shu.edu/~blackdav



Sat, 29 May 2004 23:25:04 GMT  
 Hash.keys Q

L> Now options.keys returns ["Password", "Host", "Port", "Name"]

L> I would expect ["Host", "Port", "Name", "Password"]

L> is there an explanation for this ?

 Yes, the order of the keys in an Hash depend of the hash function. For
 example in your case, the order is given by

pigeon% cat b.rb
#!/usr/bin/ruby
["Password", "Host", "Port", "Name"].each do |key|
   puts "#{key} -- #{key.hash % 10}"
end
pigeon%

pigeon% b.rb
Password -- 2
Host -- 7
Port -- 8
Name -- 9
pigeon%

 10 is the default size value when ruby build an Hash

Guy Decoux



Sat, 29 May 2004 23:30:23 GMT  
 Hash.keys Q
[snip]

Quote:
>> Now options.keys returns ["Password", "Host", "Port", "Name"]

>> I would expect ["Host", "Port", "Name", "Password"]

>> is there an explanation for this ?

> Yes: the order of hash keys is not guaranteed.  I *think* #keys
> returns the keys in the same order when called multiple times, but I'm
> not 100% sure.  In any case, that order itself cannot be predicted.

> I believe various people have written various OrderedHash
> extensions... (very helpful advice, I know :-) You could search on
> <http://www.ruby-talk.org> to see if there's been discussion here.

Theres one at http://sourceforge.net/projects/rubycollections/

Look for rubycollections/rbc/sorted_hash.rb under CVS.

Jason Voegele



Sat, 29 May 2004 23:30:23 GMT  
 Hash.keys Q
Den 12-12 2001 kl. 12:21:38 +0900, skrev David Alan Black:

Quote:
> Welcome to Ruby!

Thank you

Quote:
>> Now options.keys returns ["Password", "Host", "Port", "Name"]
>> I would expect ["Host", "Port", "Name", "Password"]
>> is there an explanation for this ?
> Yes: the order of hash keys is not guaranteed.  I *think* #keys
> returns the keys in the same order when called multiple times, but I'm
> not 100% sure.  In any case, that order itself cannot be predicted.

The order has been consistent so far. I wonder if the order is dependent
of the hash content, or host specific.

Quote:
> I believe various people have written various OrderedHash
> extensions... (very helpful advice, I know :-) You could search on
> <http://www.ruby-talk.org> to see if there's been discussion here.

I'll have a look, thanks

Leo
--
Non-Determinism is not meant to be reasonable.
                -- M.J. 0'Donnell



Sat, 29 May 2004 23:46:22 GMT  
 Hash.keys Q
Den 12-12 2001 kl. 12:26:31 +0900, skrev ts:

Quote:
>> Now options.keys returns ["Password", "Host", "Port", "Name"]
>> I would expect ["Host", "Port", "Name", "Password"]
>> is there an explanation for this ?
>  Yes, the order of the keys in an Hash depend of the hash function. For
>  example in your case, the order is given by
> pigeon% cat b.rb
> #!/usr/bin/ruby
> ["Password", "Host", "Port", "Name"].each do |key|
>    puts "#{key} -- #{key.hash % 10}"
> end
> pigeon%
> pigeon% b.rb
> Password -- 2
> Host -- 7
> Port -- 8
> Name -- 9
> pigeon%
>  10 is the default size value when ruby build an Hash

This is excellent!
To be honest i don't understand it fully, but at least I know what to
look for in my studies. Thanks.

Leo
--
Al didn't smile for forty years.  You've got to admire a man like that.
                -- from "Mary Hartman, Mary Hartman"



Sun, 30 May 2004 00:02:20 GMT  
 Hash.keys Q

Quote:
>  Yes, the order of the keys in an Hash depend of the hash function. For
>  example in your case, the order is given by

The order of the keys does not depend on the hash function -
however for small hashes there is a statistical trend. I get
the output

order reversal occurred 484 out of 100000 times
order reversal occurred 0 out of 100000 times

when I run the following script

-----------
class Reversal
def self.count1 m
    normal = 0
    reverse = 0
    m.times do |i|
      e = new
      o = new
      hsh      = {e => o, o => e}
      swap_hsh = {o => e, e => o}
      if (hsh.keys == swap_hsh.keys)
        normal+=1
      else
        reverse+=1
      end
   end
   puts "order reversal occurred #{reverse} out of #{m} times"
end
def self.count2 m
    normal = 0
    reverse = 0
    e = new
    o = new
    m.times do |i|  
      hsh      = {e => o, o => e}
      swap_hsh = {o => e, e => o}
      if (hsh.keys == swap_hsh.keys)
        normal+=1
      else
        reverse+=1
      end
   end
   puts "order reversal occurred #{reverse} out of #{m} times"
end
end

Reversal.count1  10**5
Reversal.count2  10**5
-----------

/Christoph



Sun, 30 May 2004 01:41:16 GMT  
 Hash.keys Q

c> The order of the keys does not depend on the hash function -

void
st_add_direct(table, key, value)
    st_table *table;
    char *key;
    char *value;
{
    unsigned int hash_val, bin_pos;

    hash_val = do_hash(key, table);
    bin_pos = hash_val % table->num_bins;
    ADD_DIRECT(table, key, value, hash_val, bin_pos);

Quote:
}

 Just look what do do_hash() (hint : it call the hash function)

c> however for small hashes there is a statistical trend

 I suspect that you have just seen the effect of modulo with num_bins

Guy Decoux



Sun, 30 May 2004 01:49:01 GMT  
 Hash.keys Q

Quote:

>  I suspect that you have just seen the effect of modulo with num_bins

Yeap this is the complete explanation. My point was that the
hash value alone does not determine the order of the keys if
collision occurs. The up shoot is that the apparent determinism
of the key ordering for small hashes is just a implementation fluke
related to the of the initial bucket size and the (non-equiv)
distribution of hash values.

/Christoph



Sun, 30 May 2004 17:42:57 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. hash as key in hash

2. Hash.new(Hash.new) doesn't use Hash.new as default value

3. Accessing hash values sorted by their keys

4. sort the hash keys

5. Checking hash key's and values, with case insensitivity

6. Primary Key Hash help

7. valid hash keys

8. Auto-quoting simple hash keys?

9. using my own objects as hash keys - a question

10. Symbols, and their use as hash keys

11. Hash with a key of nil ?

12. Modifying Hash Table Keys

 

 
Powered by phpBB® Forum Software