[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] "rewinding" a file



At 18:51 96-06-19, John Springer wrote:

>Maybe there's a better way to do what I'm trying to do, which is:
>I want to choose records from a file according to some criteria.
>Accumulate the chosen records; the number might be large (1000?).
>Sort the chosen records by a $keyfield
>Report the sorted results.

Why get caught up in file handling when Perl already gives you what you
really want: random access by key, a.k.a. an associative array.

Here's the approach I'd use:
- keep the choosen records in an associative array
- use the keyfield as the key (making it unique if need be)
- map the associative array to a dbm file so you don't have to worry
about memory issues

In untested Perl4 code, that's:
#!perl

$dbmFile = 'tempfile';

dbmopen( %a, $dbmFile, 0666 )
    || die( "Can't open dbm file '$dbmFile': $!\n" );

while( <> ) {
    if( /(key)whatever/ ) {
        $key = $1; # or whatever
        # you only need the following 3 lines if keys aren't unique
        $keyindex = 0;
        $keyindex++ while defined( $a{ "$1$keyindex" } );
        $key .= $keyindex;
        # end of non-unique key handling

        $a{ $key } = $_; # or whatever part of record you want
    }
}

foreach $key (sort keys( %a ) ) {
    print $a{ $key };
}

dbmclose( %a ) || die( "Can't close dbm file '$dbmFile': $!\n" );
unlink( $dbmFile ) || die( "Can't delete dbm file '$dbmFile': $!\n" );

Note: if performance is a problem, you can increase the number of
elements of the associative array that will be cached in memory.  See
the man pages for dbmopen for details.

--Hal
Hal Wine <hal@dtor.com>     voice: 510/482-0597