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 bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Ready to learn complex data types

Status
Not open for further replies.

ejaggers

Programmer
Feb 26, 2005
148
US
I wrote a utility awhile back that gives me DBA info using Informix onstat commands. The following is the onstat –g ses command, which I want to see sorted 4 different ways.
So I created 4 hashes. I’m not familiar with complex data structures because I taught myself Perl, and I’m not there yet. I haven’t used array of hashes, anonymous data types, etc yet, but would like to learn.

Since all 4 hashes contain the exact same info but different keys, I’m sure there is a better way to do this. What do ya’ll think is a better way?

Code:
@input = (
 'onstat headers ....',
 '3214     informix -        0        -        0        12288      11384      off',
 '3211     sifagent IISD-SIF 8072     10.37.11 1        86016      52368      off',
 '3209     sifagent IISD-SIF 4880     10.37.11 1        90112      52392      off',
 '3203     tblough  22       106643   irv001   1        475136     446688     off',
 '3101     dwilliam 5        86562    irv001   1        1155072    1100144    off',
 '3100     dwilliam 5        86329    irv001   1        282624     263424     off',
 '3040     adavila  10       76856    irv001   1        2490368    2440584    off',
);

foreach (@input) {
   next unless /^\d/;
   my (@field) = split;
   my $sid        =  ' ' x ( 8 - length($field[0])) . $field[0]; 
   my $username   =  $field[1] . ' ' x ( 8 - length($field[1])); 
   my $tty        =  $field[2] . ' ' x ( 8 - length($field[2]));
   my $pid        =  $field[3] . ' ' x ( 8 - length($field[3]));
   my $memory     =  ' ' x (12 - length($field[6])) . $field[6];
   
   $SID{$sid}               =  "$sid  $username   $tty   $pid $memory\n";
   $Memory{"$memory $sid"}  =  "$sid  $username   $tty   $pid $memory\n";
   $User{"$username $sid"}  =  "$sid  $username   $tty   $pid $memory\n";  
   $PID{$pid}               =  "$sid  $username   $tty   $pid $memory\n";    
}
print "$SID{$_}"  foreach (sort keys %SID);
 
Instead of jumping off the deep end why not start in the shallow end? The first three tutorials on this page discuss references (complex data strutures):


First learn the syntax for creating references and for dereferencing them. Its really actually quite simple once you get over the shock of seeing the strange new syntax, for example:

Code:
push @{$hash{key}} , [list of stuff];

The most difficult concept at times is remembering that a reference to some data affects the original data when you do something to the reference. A short example:

Code:
@array = (1..10);
my $ref = \@array;#<-- reference to the original @array
$_++ for @{$ref};
print "@array";

To avoid that behavior you have to make a new copy of the original data:

Code:
@array = (1..10);
my $ref = [@array];#<-- makes a copy of @array
$_++ for @{$ref};
print "@array";

You might be scratching your head about now, read the tutorials, then start with some simple data and build up to more complex data.









------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
KevinADC, I've wet my feet with referencing and dereferencing. I’ve done this:

Sub1(\%hash);
sub Sub1 {
my $hashref = shift;
print $$hashref {$_} foreach ( sort keys $%hashref );
}

So I’m ready for the next step. But I admit that the -> notation is confusing to me. I’m off tomorrow and will check back in on Monday.
 
You will want to quickly forget about using soft references and stick with hard references which will work when using "strict", where soft references will not.

The next step is to read the tutorials I linked you up to. After you read them you should pretty much be good to go.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Note that if one of the keys has duplicate values, the 4 hashes won't even contain the same number of elements!
If you don't have a huge amount of data and you just need to sort the data in 4 different ways, then what you have done is likely the best way to go (except for the preceding comment).
Otherwise you can try what follows (untested)
Code:
@mydata=map{[split]}@input
  #sort by $sid
map{printf("%8s  %-11s%-11s%-9s%12s\n",@$_[0..3],$$_[6])}sort{$$a[0]<=>$$b[0]}@mydata
  #sort by $username $sid
map{printf("%8s  %-11s%-11s%-9s%12s\n",@$_[0..3],$$_[6])}sort{$$a[1]cmp$$b[1]||$$a[0]<=>$$b[0]}@mydata
The details of how to sort could depend on the type of data you have and what you want to get: e.g. $sid is numeric and if it is not fixed width, your way of sorting it won't produce a numeric sorting, my way is purely numeric (but I don't know what you really need).
Also note the clearer and more compact way of producing your formatted lines.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
prex1,
Note that if one of the keys has duplicate values
I have to insure that the hash key is unique (i.e. $User{"$username $sid"}).

As for the example you supplied, it's way over my head. The only thing I recognize is the printf for spacing. I would like to learn complex data structures but I am by no means, there yet.

KevinADC, I read some of the tutorials you supplied which tells you how, but not which structure to use. What do you reccomend?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top