Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

create hashes from a hash

Status
Not open for further replies.

rshandy

Technical User
Dec 26, 2003
91
US
Still a newb so bear with me: I'm trying bring in data from a flatfile db and place into a hash and then create a subset of that common data. For example, I have product groupings that have multiple multiple colors in multiple sizes. I want to be able to group all skus that are size M,L, etc. I will not, however, know the size variables as every product series has its own size designations(S,M and L, and then maybe 22, 26, 28, etc).
Below is a sampling of a tab delimited file:

123400 xyz
123411 xyz M Blue
123412 xyz M Green
123413 xyz M Red
123414 xyz L Olive
123426 xyz L Blue
123445 xyz XS Blue
123467 xyz S Red
123467 xyz S Gray
etc...
---------------------
This is what I have so far. I'm able bring the data in and print ok, but I can't figure out how to get new hashes grouped by Size:

while () {
$in = <FILE>;
if ($in) {
($SKU,$Product_Series,$Color_Finish,$Size)=split('\t',$in);
if ($Product_Series eq $crate_series) {
$subsku=substr($SKU,5,2);
if ($subsku eq "00") {
}else{
$ProductSeries{$SKU} = {'Size' => $Size,'Color_Finish' => $Color_Finish};

} else{ last; } # end of Database

}
foreach $SKU(sort keys %ProductSeries) {
print " $SKU: ";
print "Product Size: $ProductSeries{$SKU}{Size} - ";
print "Color finish: $ProductSeries{$SKU}{Color_Finish}<br>";
}

Thanks, Rich
 
the code you have posted is not valid. The very first 'if' condition was never terminated so you have two else{} conditions in a row. That is not valid in perl.

The split looks incorrect based on the variable names and the data you posted:

Code:
($SKU,$Product_Series,$Color_Finish,$Size)=split('\t',$in);[]/code]

$Color_Finish should be after $Size?

This series of lines:

[code]
    while () {
    $in = <FILE>;                                            
    if ($in) {

is better written as:

Code:
while ($in = <FILE>) {

stop now and start using "strict" and "warnings":

Code:
#!/usr/bin/perl
use strict;
use warnings;

they will help you write good and valid perl code.

- Kevin, perl coder unexceptional!
 
Repost:

the code you have posted is not valid. The very first 'if' condition was never terminated so you have two else{} conditions in a row. That is not valid in perl.

The split looks incorrect based on the variable names and the data you posted:

Code:
($SKU,$Product_Series,$Color_Finish,$Size)=split('\t',$in);

$Color_Finish should be after $Size?

This series of lines:

Code:
    while () {
    $in = <FILE>;                                            
    if ($in) {

is better written as:

Code:
while ($in = <FILE>) {

stop now and start using "strict" and "warnings":

Code:
#!/usr/bin/perl
use strict;
use warnings;

they will help you write good and valid perl code.

- Kevin, perl coder unexceptional!
 
Sorry, Kevin.

This is only a subroutine called from a larger perl program I'm writing.

Also, the flatfile is over 30 fields, so I cut and pasted only the fields I was extracting to perform the size matching and cut and pasted improperly.


The resultant was accidentally posted with the data flipped. it should read:

123400 xyz
123411 xyz Blue M
123412 xyz Green M
123413 xyz Red M
123414 xyz Olive L
123426 xyz Blue L
123445 xyz Blue XS
123467 xyz Red S
123467 xyz Gray S
etc...

Beginning of the file:

#!/usr/local/bin/perl5
use strict;
use CGI qw:)standard);
use warnings;

The subroutine below is called from the main body of the program. $crate_series is defined from a html form submission:

sub read_inputDB2 {
my $subsku;
my $modeltotal=0;
my $in=''; #temp input line
my ($SKU,$Product_Series,$Color_Finish,$Size); #all data for dog doors
my %ccbook=();
my %ProductSeries=();
&databasepickDB();
open (FILE, "$ccbookdb") or die "Cannot open ccbook database ($ccbookdb):$!\n";

while () {
$in = <FILE>; #skusand data
if ($in) {
($SKU,$Product_Series,$Color_Finish,$Size)=split('\t',$in);
if ($Product_Series eq $crate_series) {
$subsku=substr($SKU,5,2);
if ($subsku eq "00") {
}else{
$ProductSeries{$SKU} = {'Size' => $Size,'Color_Finish' => $Color_Finish};
}
}
} else{ last; } # end of Database

}
foreach $SKU(sort keys %ProductSeries) {
print " $SKU: ";
print "Product Size is = $ProductSeries{$SKU}{Size} - ";
print "Color is: $ProductSeries{$SKU}{Color_Finish}<br>";
}

close FILE;
}


Once again, I appologize for the mixup! Any help would be greatly appreciated,

Thanks again,

Rich
 
There are many ways to structure the data. Without knowing anymore than than the code I see, I think what you want is a hash of arrays, maybe something like:

Code:
while (my $in = <FILE>) {
    my ($SKU, $P_S, $C_F, $Size)=split(/\s+/,$in);
    if ($P_S eq $crate_series) {
       my $subsku=substr($SKU,4,2);
       if ($subsku eq "00") {
       }
       else{
          push @{ $ProductSeries{SKU}{$SKU} }  , {SKU => $SKU, 'Size' => $Size, 'C_F' => $C_F};
          push @{ $ProductSeries{SIZE}{$Size} }, {SKU => $SKU, 'Size' => $Size, 'C_F' => $C_F};
          push @{ $ProductSeries{P_S}{$P_S} }  , {SKU => $SKU, 'Size' => $Size, 'C_F' => $C_F};
       }
    }
}


- Kevin, perl coder unexceptional!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top