New to Perl. Need some guidance with what to do..

S

scadav

I am pretty new to perl so I am hoping someone can give me some direction
with the following problem.

I have a log file which tracks orders that are placed. If a customer
places an order, that order will be given a unique identifier. If the
customers decides to change the order, the replaced order will be given a
new identifier (replacing the old one). For example:



Item OrderID OldOrderID Quantity
xyz 1234 NONE 200
xyz 1235 1234 150
xyz 1427 1235 175
abc 4561 NONE 200
abc 8541 4561 450
xyz 1785 1427 250
xyz 1263 1785 800
jot 4715 NONE 12
nuy 7894 NONE 856
xyz 8978 NONE 741 **** (New different order for
XYZ)



Here is what the actual log file looks like:
xyz|1234|NONE|200
xyz|1235|1234|150
xyz|1427|1235|175
abc|4561|NONE|200
abc|8541|4561|450
xyz|1785|1427|250
xyz|1263|1785|800
jot|4715|NONE|12
nuy|7894|NONE|856
xyz|8978|NONE|741



In this example, the order for xyz changed 5 times and I would like to
create a list of all the id numbers that are associated with that one
order that was changed 5 times. Keep in mind that the log file will
contain other orders for xyz, but they are NEW orders and not CHANGED
orders. For example, this would be the output I am looking for:

1234
1235
1427
1785
1263

I figured the best way to go about this was to try to put the values into
an array. Well, I can get the first two ids into the array, but I am not
sure how to continue to search from the last item I put into the array
and keep comparing to the has I created. Not sure if that makes sense or
not. Anyhow below is the code that I created. Can anyone point me in
the correct direction?

Thanks



#######################################################
use strict;

my $logfile=();
my $rcd=();
my @row=();
my %cxlrepl=();
my $orderid=();

my $oldid=();
my $newid=();

my @idlist=();

my $ab=();

$orderid = 1234;
$logfile = "temp.txt";

open (DATA, $logfile) || die ("cannot open file");

while ($rcd = <DATA>){
next unless (!($rcd =~ /NONE/));
@row = split(/\|/,$rcd);
$cxlrepl{$row[2]}=$row[1];
}

push (@idlist, $orderid);

while (($oldid, $newid) = each(%cxlrepl)){

if ($orderid == $oldid){
push (@idlist, $newid);
}

}



foreach (@idlist){
print "$_ \n";
}
#####################################################
 
R

Richard Trahan

# log.pl

use strict;

my %h;
my $start = -1; # dummy hash key
open(FIN,"<","log.txt");
while(<FIN>) {
chomp;
my(undef,$id,$oid,undef) = split(/\|/);
if($oid eq "NONE") { # start of chain
$oid = $start--; #unique dummy key
}
$h{$oid} = $id; # like $h{-1} = 1234; $h{1234} = 1235
}
close(FIN);

# print sequences

foreach my $k(sort keys %h) {
next unless $k < 0; # gives us -1, -2, -3, ...
my $y = $h{$k}; # ignore dummy key
while($y) {
print "$y\n";
$y = $h{$y};
}
print "\n\n";
}
 
T

Tad McClellan

scadav said:
I have a log file which tracks orders that are placed. If a customer
places an order, that order will be given a unique identifier. If the
customers decides to change the order, the replaced order will be given a
new identifier (replacing the old one).

In this example, the order for xyz changed 5 times and I would like to
create a list of all the id numbers that are associated with that one
order that was changed 5 times. Keep in mind that the log file will
contain other orders for xyz, but they are NEW orders and not CHANGED
orders. For example, this would be the output I am looking for:

1234
1235
1427
1785
1263

Can anyone point me in
the correct direction?


I'd use a HoL data structure, keyed by item name:

-----------------------------------
#!/usr/bin/perl
use warnings;
use strict;

my %items; # hash of references to arrays
while ( <DATA> ) {
my( $item, $id, $prev ) = split /\|/;
if ( $prev eq 'NONE' and exists $items{$item} ) {
print "$item\n";
print " $_\n" for @{ $items{$item} }; # output before stomping on it
print "\n";
@{ $items{$item} } = $id; # "Use Rule 1" from perldoc perlreftut
}
else {
push @{ $items{$item} }, $id;
}
}

foreach my $item ( sort keys %items ) {
print "$item\n";
print " $_\n" for @{ $items{$item} }; # output the "last of their kind"
print "\n";
}

__DATA__
xyz|1234|NONE|200
xyz|1235|1234|150
xyz|1427|1235|175
abc|4561|NONE|200
abc|8541|4561|450
xyz|1785|1427|250
xyz|1263|1785|800
jot|4715|NONE|12
nuy|7894|NONE|856
xyz|8978|NONE|741
xyz|8980|8978|740
xyz|8990|8980|700
 
S

scadav

Thanks for everyones help.


Tad McClellan said:
I'd use a HoL data structure, keyed by item name:

-----------------------------------
#!/usr/bin/perl
use warnings;
use strict;

my %items; # hash of references to arrays
while ( <DATA> ) {
my( $item, $id, $prev ) = split /\|/;
if ( $prev eq 'NONE' and exists $items{$item} ) {
print "$item\n";
print " $_\n" for @{ $items{$item} }; # output before stomping on it
print "\n";
@{ $items{$item} } = $id; # "Use Rule 1" from perldoc perlreftut
}
else {
push @{ $items{$item} }, $id;
}
}

foreach my $item ( sort keys %items ) {
print "$item\n";
print " $_\n" for @{ $items{$item} }; # output the "last of their kind"
print "\n";
}

__DATA__
xyz|1234|NONE|200
xyz|1235|1234|150
xyz|1427|1235|175
abc|4561|NONE|200
abc|8541|4561|450
xyz|1785|1427|250
xyz|1263|1785|800
jot|4715|NONE|12
nuy|7894|NONE|856
xyz|8978|NONE|741
xyz|8980|8978|740
xyz|8990|8980|700
-----------------------------------
 
M

Mladen Gogala

Thanks for everyones help.

Hopefully, you're aware that this a job for a relational
database combined with perl. That will save you infinite
pain and grief later.
 

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,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top