> HI,
> I want to provide remittance slips to my suppliers. I've extracted data
> from my payments database and pushed records into an array. Here is a
> sample of data from that array :
>
> 01,supplierA,100.00,1st May 2005
> 02,supplierB,100.00,3rd May 2005
> 03,supplierC,100.00,3rd May 2005
> 04,supplierA,100.00,4th May 2005
>
> I would identify the fields thus :
>
> foreach $item(@array) {
> ($transaction,$supplier,$amount,$pay_date) = split /,/,$item;
> }
>
> This allows me to print a remittance by transaction(record) but I need some
> sort of grouping mechanism to group transactions belonging to the same
> supplier.
> In other words - although the sample above has 4 transactions, it should
> only produce 3 remittance slips.
> Cheers,
> Mark
Here is a technique that uses some complex data structures. Read
the Perl Data Structures Cookbook ( perldoc perldsc ) if any of this is not
obviously clear to you.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
#
# For each of several transactions, add one line to a slip
#
sub Produce_remittance_slip ($@)
{
my ($supplier, @transaction) = @_ ;
print "begin slip for $supplier\n";
for my $transaction (@transaction) {
print
'Transaction: ',
$transaction->{serial},
' on ',
$transaction->{pay_date},
' amount: ',
$transaction->{amount},"\n";
}
print "end slip for $supplier\n\n\n";
}
#
# a hash to hold a arrayref of transaction details for
# each supplier
#
my %transaction;
while (<DATA>) {
#
# a little hashref to hold the details of one record
#
my $details ;
#
# since you sent this question to the DBI list as well
# as the beginners list, you might want to consider
# using the fetchrow_hashref() DBI method
# such that $details will already BE a hashref
# of the form $details = { serial => '123',
# supplier => 'Wombly Bog Bitters',
# amount => '150.00',
# date => '21st May' }
#
#
# use a hash-slice to populate the record from the data file row
#
chomp;
@$details{qw / serial supplier amount pay_date / } = split ',';
#
# this following line is equivalent to the following:
# $transactions_for_this_supplier = $transaction{$details->{supplier}};
# push @$transactions_for_this_supplier, $details;
#
# but that will not work quite right, because
# you don't get autovifification.
#
# you could MAKE it work by making sure each supplier
# has an empty arrayref in %transaction
# with a line like
#
# $transaction{$details->{supplier}} ||= [];
#
# but I think that notation is more confusing than
# mastering this rather-common idiom:
#
push @{$transaction{$details->{supplier}}}, $details;
}
#
# now, %transaction looks like
#
# %transaction = (
# 'supplierB' => [
# {
# 'amount' => '100.00',
# 'pay_date' => '3rd May 2005',
# 'supplier' => 'supplierB',
# 'serial' => '02'
# }
# ],
# 'supplierA' => [
# {
# 'amount' => '100.00',
# 'pay_date' => '1st May 2005',
# 'supplier' => 'supplierA',
# 'serial' => '01'
# },
# {
# 'amount' => '100.00',
# 'pay_date' => '4th May 2005',
# 'supplier' => 'supplierA',
# 'serial' => '04'
# }
# ],
# 'supplierC' => [
# {
# 'amount' => '100.00',
# 'pay_date' => '3rd May 2005',
# 'supplier' => 'supplierC',
# 'serial' => '03'
# }
# ]
# );
#
# now, for each supplier, produce a remittance slip with each of their
transactions
#
for my $supplier ( sort { $a cmp $b } keys %transaction ) {
my @transaction = @{$transaction{$supplier}};
Produce_remittance_slip ($supplier, @transaction );
}
__DATA__
01,supplierA,100.00,1st May 2005
02,supplierB,100.00,3rd May 2005
03,supplierC,100.00,3rd May 2005
04,supplierA,100.00,4th May 2005
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Lawrence Statton - [EMAIL PROTECTED] s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
sort them into the correct order.