Get values from hash "in order"

S

still just me

Newbie hash question:

I have a hash loaded with keys / values. I need to pull the values out
in the same order I have them physically listed in the source program
(or use some scheme to achieve that).

I pulled them like this:

my $tempValue="";
foreach $tempValue (values %outputFileHeadings)
{
$outputMessage = $outputMessage . $tempValue
}

They seem to come out in a random order. Is there some way to pull
them in the same order they are physically listed in the program ?
 
J

John Bokma

still just me said:
Newbie hash question:

I have a hash loaded with keys / values. I need to pull the values out
in the same order I have them physically listed in the source program
(or use some scheme to achieve that).

I pulled them like this:

my $tempValue="";
foreach $tempValue (values %outputFileHeadings)
{
$outputMessage = $outputMessage . $tempValue
}

They seem to come out in a random order. Is there some way to pull
them in the same order they are physically listed in the program ?

perldoc -q order
 
J

Jürgen Exner

still said:
Newbie hash question:

I have a hash loaded with keys / values. I need to pull the values out
in the same order I have them physically listed in the source program

Then you are using an inappropriate data structure. Hashes by their very
nature do not have any odering, therefore they can't preserve something that
doesn't even exist in their world.
(or use some scheme to achieve that).

Use a data structure that supports the concept of sequences like an array.
They seem to come out in a random order.

That is by design.
Is there some way to pull
them in the same order they are physically listed in the program ?

No.

jue
 
S

smallpond

Newbie hash question:

I have a hash loaded with keys / values. I need to pull the values out
in the same order I have them physically listed in the source program
(or use some scheme to achieve that).

I pulled them like this:

my $tempValue="";
foreach $tempValue (values %outputFileHeadings)
{
$outputMessage = $outputMessage . $tempValue
}

They seem to come out in a random order. Is there some way to pull
them in the same order they are physically listed in the program ?


foreach $key (key1, key2, key3, key4, ... ) {
$tempValue = $outputFileHeadings{$key};
$outputMessage = $outputMessage . $tempValue;
}
 
B

Ben Morrow

Quoth still just me said:
Newbie hash question:

I have a hash loaded with keys / values. I need to pull the values out
in the same order I have them physically listed in the source program

This is a FAQ: perldoc -q order.

Ben
 
S

still just me

foreach $key (key1, key2, key3, key4, ... ) {
$tempValue = $outputFileHeadings{$key};
$outputMessage = $outputMessage . $tempValue;
}


Thanks all. I will try out some of the suggestions.

Is there some advantage to Perl in them storing in random order?
Perhaps some internal storage efficiency?
 
J

Joost Diepenmaat

Thanks all. I will try out some of the suggestions.

Is there some advantage to Perl in them storing in random order? Perhaps
some internal storage efficiency?

It's mainly lookup effiency. IOW it makes it really fast to find or
insert an entry in a hash.

See http://en.wikipedia.org/wiki/Hash_table or any good programming /
datastructures book.

Joost.
 
J

Jürgen Exner

still just me wrote:
[about hashes]
Is there some advantage to Perl in them storing in random order?
Perhaps some internal storage efficiency?

Actually the order in which e.g. each() or keys() cycles through the items
of a hash is not random at all but it is well defined and guaranteed to be
the same for every access to that hash. It is just that this sequence
doesn't make any sense to the programmer because this sequence is -as you
suspected- based on the internal implementation and not on some human
expectation about useful order.

However, on an abstract level, hashes are a generalization of arrays. Arrays
are mappings from natural numbers (assuming you didn't mess with $[) into
scalars while hashes are mappings from arbitrary strings into scalars.
Natural numbers have an inherent sequence, there is a natural next and
previous. Therefore you can specify a concrete point in the array and from
there access the next and the previous element.
There is no such obvious sequence for strings. Alphabetical sorting is not
compact, i.e. between any two given strings there is always another string.
And incremental strings as produced by the ++ operator are not what people
would expect from a sorted hash.

And because there is no such obvious order on the domain elements of hashes
as is are the natural numbers for arrays it doesn't make sense to speak of a
sequence of the elements of hashes. Sequence of order is foreign to hashes.

jue
 
T

Tad J McClellan

[snip: hashes are unorderd]

Is there some advantage to Perl in them storing in random order?


This is not about Perl, it is about hashing, whether in Perl or not.

(try Googling for "hashing")
 
P

Peter J. Holzer

still just me wrote:
[about hashes]
Is there some advantage to Perl in them storing in random order?
Perhaps some internal storage efficiency?

Actually the order in which e.g. each() or keys() cycles through the items
of a hash is not random at all but it is well defined and guaranteed to be
the same for every access to that hash.

Actually, that's only guaranteed if no elements are added or removed
between accesses. Adding or removing elements may completely change the
order.

Actually I'm surprised that

#!/usr/bin/perl

for ( "aa" .. "bz") {
$x{$_} = 1;
}

for (keys %x) {
print "$_\n";
}
__END__

always produces the same file. IIRC some early 5.8.x version introduced
a random seed value which would ensure that the order is different for
each run. Apparently this was dropped again.

hp
 
J

Jürgen Exner

Peter said:
still just me wrote:
[about hashes]
Is there some advantage to Perl in them storing in random order?
Perhaps some internal storage efficiency?

Actually the order in which e.g. each() or keys() cycles through the
items of a hash is not random at all but it is well defined and
guaranteed to be the same for every access to that hash.

Actually, that's only guaranteed if no elements are added or removed
between accesses. Adding or removing elements may completely change
the order.

Quite right, should have mentioned that. Thank you.

jue
 
B

Ben Morrow

Quoth "Peter J. Holzer said:
Actually, that's only guaranteed if no elements are added or removed
between accesses. Adding or removing elements may completely change the
order.

Adding may, removing never will.
Actually I'm surprised that
always produces the same file. IIRC some early 5.8.x version introduced
a random seed value which would ensure that the order is different for
each run. Apparently this was dropped again.

No, it's still there. It only gets invokes when a hash starts behaving
pathologically. If you download the file
http://www.cs.rice.edu/~scrosby/hash/attack/perl-5.8.0-attack.gz and
gunzip it, then

perl -e'@h{<>} = (); print +(keys %h)[0]' perl-5.8.0-attack

will give a different answer every time.

Ben
 

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,770
Messages
2,569,586
Members
45,096
Latest member
ThurmanCre

Latest Threads

Top