shaolin_gungfu has asked for the wisdom of the Perl Monks concerning the following question:

Hi folks,
Can someone help me please? I've looked through the tutorials and Q&A sections with no luck...

I need to know how to do one of the following.

1. Is it possible to write an array to disk in the same way as you can a hash, with either the dbmopen/dbmclose or that tiehash thing?

or

2. How can I sequentially step through elements in a hash? For example with an array I would just 'push' things on, then I 'shift' them off.

or

3. If I don't know the key from my hash, how can I just retrieve the first value?

Thanks Tom

Replies are listed 'Best First'.
Re: Fun with arrays and hashes
by broquaint (Abbot) on Apr 16, 2002 at 15:13 UTC
    1. Is it possible to write an array to disk in the same way as you can a hash, with either the dbmopen/dbmclose or that tiehash thing?
    You surely can. With what I don't know as I'm unfamiliar with dbmopen() and dbmclose() (which are deprecated incidentally), but it's definitely possible.
    2. How can I sequentially step through elements in a hash? For example with an array I would just 'push' things on, then I 'shift' them off.
    You can't as hashes are inherently unordered.
    3. If I don't know the key from my hash, how can I just retrieve the first value?
    Since hashes aren't ordered you can't retrieve the first value. You could always sort() on the keys() in the hash which you could then iterate through in the resulting order.

    For more info on hashes and arrays check out the official manpage on perl's data types, or pick up a copy of Learning Perl.
    HTH

    broquaint

Re: Fun with arrays and hashes
by perlplexer (Hermit) on Apr 16, 2002 at 15:14 UTC
    1. Is it possible to write an array to disk in the same way as you can a hash, with either the dbmopen/dbmclose or that tiehash thing?

    You can design a class which will do that for you. Take a look at perldoc -f tie

    How can I sequentially step through elements in a hash? For example with an array I would just 'push' things on, then I 'shift' them off

    Use each.

    If I don't know the key from my hash, how can I just retrieve the first value

    In a hash, there is no such thing as "the first value" because hashes are not ordered. You can get _a_ value from your hash by using each().

    Example
    my %hash = ('foo' => 'bar', 'bar' => 'foo'); my ($key, $val) = each(%hash); print "$key\n";

    --perlplexer
Re: Fun with arrays and hashes
by moodster (Hermit) on Apr 16, 2002 at 15:23 UTC
    1. I haven't meddled with dbmopen or tiehash, but you could always check out the Tie::Array module. Or go with Storable, which is included in the standard distribution and will store anything.

    2 & 3. A hash is not ordered, so there is no way to access the 'first' element. However, the keys( %hash ) function returns an array of the keys of a hash. This array is not ordered and calling keys repeatedly may or may not yield the same results. A common construct is to sort the keys before looping over the array; this will step through the hash in the alpabetical order of the keys, which is nearly but not really the same thing you are asking for in 2)

    for my $key ( sort keys %myhash ) { print "$key: $myhash($key)\n"; }

    Cheers,
    --Moodster

Re: Fun with arrays and hashes
by strat (Canon) on Apr 16, 2002 at 15:34 UTC
    Hello,

    1. I don't know if it is possible with dbmopen/dbmclose because I hardly use this

    2. Yes, you can:

    foreach my $key (keys %hash){ print "$key => $hash{$key}\n"; } # or shorter: foreach (keys %hash){ print "$_ => $hash{$_}\n"; }
    or in a different way:
    while ( my ($key, $value) = each (%hash)){ print "$key => $value\n"; }

    shift, unshift, push or pop don't work with hashes; just add a hashelement with a new key, and it is about unshift or push:  $hash{newKey} = 'newValue';

    3. get all keys with  my @keys = keys %hash; and choose which one you want... e.g. with: my $firstKey = ( keys %hash)[0];
    Beware that hashes are not sorted, so getting the first key might not be exactly what you want. Or do you work with Tie::Hash?

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

Re: Fun with arrays and hashes
by xtype (Deacon) on Apr 16, 2002 at 15:25 UTC
    1. Yes, by several means.
    use Storable; store (\@array, "/path/to/array.dat"); my @newarray = @{retrieve("/path/to/array.dat")};
    2. and 3.
    while(<>) { /^(.+)\: (.+)$/; my $key = $1 my @values = split(", ", $2); $hash{$key} = \@values; } foreach my $key (sort keys %hash) { print "$key: ", join(", ", @{$hash{$key}}), "\n"; }


    I hope that I understood what you were asking. -xtype