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

This node falls below the community's minimum standard of quality and will not be displayed.

Replies are listed 'Best First'.
Oh boy! A (mildly) complex data structure when there's no DB around
by OeufMayo (Curate) on Mar 27, 2001 at 04:51 UTC

    Allright, let's put it straight, I don't like to write other's code as I don't like others to write the code I'm in charge with. But, having said that, and having talk with qball in the CB, his problem was more interresting than it first sounded as he couldn't use a proper database to do the job (which obviously, would have been the best solution)

    So, after having toyed with the idea of using DBD::RAM, it seemed that this very cool module wasn't able to fill the task (which I doubt, but I haven't tried to do it with it...)

    So, here's my code:

    #!/usr/bin/perl -w use strict; my $datas = {}; my %types; ##open needed files to use in program open(NAMES, "file1.csv") or die "Can't open NAMES file: $!\n"; open(TYPES, "file2.csv") or die "Can't open TYPES file: $!\n"; open(INFO, "file3.csv") or die "Can't open INFO file: $!\n"; # Process INFO while (<INFO>){ chomp; my ($unused_col, $type_name, $name_col) = split(/,/, $_, 3); $types{$type_name} = undef; # We never knows from this table where + # these fields are linked from? } close INFO; # Process NAMES while (<NAMES>){ chomp; my ($name_id, $c_name) = split(/,/, $_, 2); $datas->{$name_id} = {'c_name' => $c_name } # provided the id i +s unique } close NAMES; # Process TYPES while (<TYPES>){ chomp; my ($type_id, $name_id, $type_name) = split(/,/, $_, 3); push @{$datas->{$name_id}->{'type_name'}}, $type_name; # Not sure if we have to test the existence of the type. # Can't hurt too much (and avoid undesired autovivification?) $types{$type_name}++ if exists $types{$type_name}; } close TYPES; # Not seen output print "Not seen:\n"; foreach (keys %types){ print "$_\n" unless $types{$_} } # Names count print "Names total count:\n"; foreach (keys %{$datas}){ print $datas->{$_}->{'c_name'} . ": " . scalar(@{$datas->{$_}->{'type_name'}}) . "\n"; }

    I guess there's a cleaner implementation of this. Mmmh, well I'll get back to DBD::RAM, I'm pretty sure it could do the job just fine...

    Cheers,
    -- Briac

    <kbd>--
    my $OeufMayo = new PerlMonger::Paris({http => 'paris.mongueurs.net'});</kbd>
      Thanks Oeuf, I didn't expect you to write up the code. Many thanks for that. Very nice code indeed. I have one question though, when I run the script against the example data my output is this:

      Not seen:
      UUUU
      IWEJ
      Names total count:
      booya: 3
      letterheadboy: 2

      Shouldn't "letterheadboy" have 4 results? Again, many thanks.
Re: oh boy!
by jeroenes (Priest) on Mar 27, 2001 at 17:45 UTC
    You can consider pulling your data with SuperSplit as well, although I would recomment DBD::CSV as arturo said.

    supersplit_open(',',"file1.csv"); would give you all your data in a 2D-array. Saves a few keystrokes.

    Jeroen
    "We are not alone"(FZ)

Re: oh boy!
by arturo (Vicar) on Mar 27, 2001 at 05:03 UTC

    I see where there's a DBD::CSV available on CPAN ...

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: oh boy!
by ok (Beadle) on Mar 27, 2001 at 02:37 UTC
    An example script to pull this data would be nice. Anyone up for the challenge?

    Is that what the professor said?
      urgh..it's not homework...here's my example script...please help...

      #!/usr/bin/perl ##BILLING PROGRAM## use strict; my(@data,@data2); ##open needed files to use in program open(FILE, "../Counts/newdata.txt") or die "Can't open file: $!\n"; open(FILE2, "../Counts/info.csv") or die "Can't open file: $!\n"; ##throw files into arrays and define arrays chomp(@data = <FILE>); chomp(@data2 = <FILE2>); ##define hash my ($id,$name,$srid); my %keyhash = ( $id => { NAME => $name, SRID => $srid, CSV => [] } ); ##populate arrays: foreach ( @data ) { ##define variables my ($id,$name,$srid) = split /,/; # Add some error checking to make sure the # hash key $id does not already exist $keyhash{$id} = { NAME => $name, SRID => $srid, CSV => [], } } ##print unused ids from csv file print "\n\nUnused ids from csv file\n"; print "--------------------------\n"; foreach ( @data2 ) { my ($id,$name,$srid) = split /,/; # Warn and do nothing if a record is found for which the # $name is not already in %keyhash unless ( defined( $keyhash{$name} ) ) { warn "No such record $id!\n"; next; } push @{$keyhash{$id}{CSV}}, [ $name, $srid ]; } ##Finally, extract the number of records for each customer ##print column headers print "\n\n"; print "Customer #of docs\n"; print "-------------------------\n"; # A little something to get the plurality correct foreach ( keys %keyhash ) { my $num = @{$keyhash{$_}{CSV}}; printf "%s %d\n", $keyhash{$_}{NAME}, $num, } ##just formatting by adding a couple returns at the end of the printou +t print "\n\n"; ##my choice of data structures ( hashes instead of arrays ) is dependa +nt ##on how we want to use the data later. ##close files close (FILE); close (FILE2); ##exit program exit;


      Here it is. Thanks for beating me up :) ..