Ordered Hash Usefulness

  • Thread starter Devi Web Development
  • Start date
D

Devi Web Development

That little challenge made me wish for some Ruby 1.9 elements, like
an ordered Hash.

James Edward Gray II

I've been wondering what the real usefulness of an ordered hash is.
Lately I've found that when I initially think of an ordered hash I
really want one of the following constructs

(1) An array of pairs
(2) A hash with multiple keys for a value.

For (2) I have implemented the second as method of hash like this:
Hash.multiple_keys([1,'str',some_object]=>'a string',[valu]=>another_object)
#=>{1=>'a string','str'=>'a
string',valu=>another_object,some_object=>'a string'}

What I really want to know is, is there some usefulness to ordered
pairs I am missing?

Daniel Brumbaugh Keeney
 
T

Trans

I've been wondering what the real usefulness of an ordered hash is.
Lately I've found that when I initially think of an ordered hash I
really want one of the following constructs

(1) An array of pairs

Slow lookup times.
(2) A hash with multiple keys for a value.

How does that behave like an ordered hash?

Thanks,
T.
 
R

Rick DeNatale

An Ordered hash presumably serves the purpose of lookup of a value by
an integer, like an array, or by a normal arbitrary key

No, for most people, based on quite a long thread referenced by Bill
Kleb, it's a normal hash except that the order that elements are
yielded by each, each_key, each_value... is defined to be the temporal
order of insertion into the hash.

In Ruby 1.8 the enumeration order of a Hash is undefined, in Ruby 1.9,
unless it's been backed out recently, it's defined as above.
 
A

ara.t.howard

What I really want to know is, is there some usefulness to ordered
pairs I am missing?

i use mine (gem install alib, alib.orderedhash.new) all the time for
generating reports in yaml.

report = alib.orderedautohash.new

report['name']['first'] = 'ara'
report['name']['last'] = 'howard'

and this make the report print the same using

y report

all the time. if you use a hash the report will have varying order
both within and between runs. ruby queue uses this for job output,
which looks like this:

-
jid: 4669
priority: 42
state: finished
submitted: 2007-11-14 09:07:36.124312
started: 2007-11-14 09:08:26.226328
finished: 2007-11-14 09:09:19.405155
elapsed: 53.178827
submitter: mussel.ngdc.noaa.gov
runner: clam.ngdc.noaa.gov
stdin: stdin/4669
stdout: stdout/4669
stderr: stderr/4669
pid: 16804
exit_status: 0
tag: eds
restartable: true
command: sif eds process_incoming /dmsp/nrt/subscriptions/eds/
incoming/F15200711141422.d.OIS
-
jid: 4670
priority: 42
state: finished
submitted: 2007-11-14 09:07:36.413314
started: 2007-11-14 09:08:26.342514
finished: 2007-11-14 09:11:44.703900
elapsed: 198.361386
submitter: mussel.ngdc.noaa.gov
runner: clam.ngdc.noaa.gov
stdin: stdin/4670
stdout: stdout/4670
stderr: stderr/4670
pid: 16860
exit_status: 0
tag: flo
restartable: true
command: sif flo process_incoming /dmsp/nrt/subscriptions/flo/
incoming/F15200711141422.d.OIS

it's *really* disorienting for users when jobs come out in different
orders job to job, and the next run dumps out something different yet
again. make using 'diff' extremely frustrating.


the other use case is for something like a database tuple or a set of
columns (mapped by name) displayed on an interface: you want to use
them by name, for instance

interface.columns['ssn']

but also want to say

interface.columns.each{|k,c| render c}

and have that come out in order. arrayfields (gem install
arrayfields) skins this cat from the other direction: allowing normal
arrays to support keyword acccess.

regards.

a @ http://codeforpeople.com/
 
R

Ralph Siegler

I've been wondering what the real usefulness of an ordered hash is.


writing one write now to deal with csv text files, like to use "column
names" internally but have to respect the proper order when writing
out.
 
R

Robert Klemme

No, for most people, based on quite a long thread referenced by Bill
Kleb, it's a normal hash except that the order that elements are
yielded by each, each_key, each_value... is defined to be the temporal
order of insertion into the hash.

Well, that's just /one/ way to order a Hash. You could as well order a
Hash by the key's natural order ( said:
In Ruby 1.8 the enumeration order of a Hash is undefined, in Ruby 1.9,
unless it's been backed out recently, it's defined as above.

Does Ruby 1.9 really impose the overhead to maintain insertion order for
*every* Hash?

Kind regards

robert
 
T

Trans

writing one write now to deal with csv text files, like to use "column
names" internally but have to respect the proper order when writing
out.

facets/dictionary, brought to you by jan molic might say you some
time. unless you're writing it in c of course --speaking if which and
good c implementations out there?

T.
 
M

MenTaLguY

Does Ruby 1.9 really impose the overhead to maintain insertion order for
*every* Hash?

I asked matz about that on ruby-core. The overhead turns out to be very
small; 1.9 maintains a doubly-linked list of hash elements, which has
constant-time insertion and removal. Memory overhead is two words per
hash element.

We may implement the 1.9 ordering in JRuby soon, as it solves a number of
problems with concurrency and iterator stability.

-mental
 
R

Ralph Siegler

facets/dictionary, brought to you by jan molic might say you some
time. unless you're writing it in c of course --speaking if which and
good c implementations out there?

thank you for pointing me at the facets project, I've been away from
following ruby-lang for awhile, some great and useful data structure
handling in there. But of course the docs and install have some
issues which I have to figure out (typical of anything gem related)


sudo task/install
task/install:18:in `initialize': No such file or directory -
meta/project.yaml (Errno::ENOENT)
from task/install:18:in `open'
from task/install:18:in `start_install'
from task/install:92


*sigh*

Ralph Siegler
 
T

Trans

thank you for pointing me at the facets project, I've been away from
following ruby-lang for awhile, some great and useful data structure
handling in there. But of course the docs and install have some
issues which I have to figure out (typical of anything gem related)

sudo task/install
task/install:18:in `initialize': No such file or directory -
meta/project.yaml (Errno::ENOENT)
from task/install:18:in `open'
from task/install:18:in `start_install'
from task/install:92

Ah, Thanks for reporting this! Sorry for the inconvenience. I'll have
a fix out this afternoon.

HTG,
T.
 
R

Robert Klemme

2007/11/21 said:
I asked matz about that on ruby-core. The overhead turns out to be very
small; 1.9 maintains a doubly-linked list of hash elements, which has
constant-time insertion and removal.

Yeah, clearly.
Memory overhead is two words per
hash element.

I'm less concerned with the CPU overhead but rather the memory overhead.
We may implement the 1.9 ordering in JRuby soon, as it solves a number of
problems with concurrency and iterator stability.

Hm, concurrently iterating and modifying is a bad idea anyway IMHO.
But I can see how some issues can be resolved with this. I just think
that making this impl. the default for all Hashes might have some
adversary effects. I'd rather leave the old impl as is and add
another (sub) class that has the ordered behavior.

Kind regards

robert
 
T

Trans

The gem install should be okay. The docs are not generated
automatically on purpose btw, b/c Facets has special doc requirements.
You can find them on-line (http://facets.rubyforge.org/learn.html).
They still have some rough edges, but I'm working on an update this
week.
Ah, Thanks for reporting this! Sorry for the inconvenience. I'll have
a fix out this afternoon.

New release 2.1.2, should fix it for you.

Let me know if you had any other problems.

T.
 
D

Daniel Sheppard

=20
Well, that's just /one/ way to order a Hash. You could as=20
well order a=20
Hash by the key's natural order (<=3D>).

Yes, but nothing extra needs to be added to Hash to get a=20
natural order enumeration - A hash.sort.each sorts that out.

An ordered hash almost always refers to insertion order, as
that's the order that is unrecoverable from a regular hash.

Dan.
 
R

Robert Klemme

2007/11/23 said:
Yes, but nothing extra needs to be added to Hash to get a
natural order enumeration - A hash.sort.each sorts that out.

Which would still be something different than a Hash that
automatically maintains this order. Granted, insertions would be
O(log(N)) instead of O(1) but lookups could still be O(1). And you
save the memory overhead of Hash#sort.
An ordered hash almost always refers to insertion order, as
that's the order that is unrecoverable from a regular hash.

I just find the terminology a bit muddy because "ordered" in itself is
too ambiguous. That's all I wanted to point out all the time.

Kind regards

robert
 
R

Ralph Siegler

Ah, Thanks for reporting this! Sorry for the inconvenience. I'll have
a fix out this afternoon.
wow, thanks much for very speedy and surprising response! It does
indeed work and well.

another minor change for it's README on next version would be to
instruct to run task/install not task/setup

I had wimped out that day and instead of using my ruby from source
installed my distro's ruby (which of course was spread over many
packages) and it's gems and then installed facets that way. An
amazing and useful collection it is.
 
J

James Edward Gray II

writing one write now to deal with csv text files, like to use "column
names" internally but have to respect the proper order when writing
out.

FasterCSV does this, if you just want an out-of-the-box solution.

James Edward Gray II
 
R

Ralph Siegler

FasterCSV does this, if you just want an out-of-the-box solution.

James Edward Gray II

thanks for bringing useful in future project to my attention (
http://fastercsv.rubyforge.org/ ) , but for what I'm doing now I'm
actually reading in a sort of "outline" and constructing multiple
product & option cvs files for database tables, the ordered hash of
facets/dictionary.rb is quite sufficient & dirty-quick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top