On Feb 19, 2008 11:12 PM,  <[EMAIL PROTECTED]> wrote:
> I am reading in a file, building an array of information that I need
> to evaluate:
>
> while (<FILE>) {
>  if ($_ =~ m/stuff/) {
>   push(@data, {'vlan' => $vlan, 'host' => $host, 'mac' => $mac, 'port'
> => $port});
>  }
> }
>
> Small sample of @data:
>
> vlan host            mac                    port
> 13      switch-1        111427f2ffff    gi1/1/49
> 13      switch-1        111511614fff    gi1/1/49
> 13      switch-1        11155e45ffff    gi1/1/49
> 13      switch-1        1115fc4753ff    gi1/1/49
> 111     switch-1        11196f977f72    gi1/1/49
> 111     switch-1        11196fff3728    gi1/1/49
> 111     switch-1        11196fe74f5f    gi1/1/49
> 111     switch-1        111f56f1fcef    gi1/1/1
> 111     switch-1        111f6123f789    gi1/1/2
> 111     switch-1        111f6124336f    gi1/1/2
> 111     switch-1        111f61245f94    gi1/1/5
> 111     switch-1        111f6147eeff    gi1/1/2
> 111     switch-1        111f61896fff    gi1/1/2
>
>
> I would like to sort the array based on the value of $data[$i]
> {'port'}.  I have a feeling that I am going about this in the wrong
> way.  Can I use hashes in a better way to sort the data based on the
> keys?  Better yet, can I evaluate the number of keys that match each
> other?
>
> I am not proficient with hashes, so I apologize in advance for my
> noobishness.  I would love to be able to understand how to make this
> work.
snip

It would be a lot easier to tell you what to do if you told us what
you wanted to achieve rather than how you want to achieve it.  If you
need to access each of those records by different methods you can use
several variables like this:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @fields = qw<vlan host mac port>; #the fields of the record

my @data; #data sequentially AoH
my %data_by; #data partitioned by key HoHoAoH

while (<DATA>) {
        my %record;
        @[EMAIL PROTECTED] = split;
        push @data, \%record;
        push @{$data_by{$_}{$record{$_}}}, \%record for @fields;
}

print Dumper([EMAIL PROTECTED], \%data_by);

print "data by port:\n";
for my $port (sort keys %{$data_by{port}}) {
        print "\tthese records have port $port:\n";
        for my $record (@{$data_by{port}{$port}}) {
                print "\t\t", join("\t", @[EMAIL PROTECTED]), "\n";
        }
}


__DATA__
13      switch-1        111427f2ffff    gi1/1/49
13      switch-1        111511614fff    gi1/1/49
13      switch-1        11155e45ffff    gi1/1/49
13      switch-1        1115fc4753ff    gi1/1/49
111     switch-1        11196f977f72    gi1/1/49
111     switch-1        11196fff3728    gi1/1/49
111     switch-1        11196fe74f5f    gi1/1/49
111     switch-1        111f56f1fcef    gi1/1/1
111     switch-1        111f6123f789    gi1/1/2
111     switch-1        111f6124336f    gi1/1/2
111     switch-1        111f61245f94    gi1/1/5
111     switch-1        111f6147eeff    gi1/1/2
111     switch-1        111f61896fff    gi1/1/2


Now, before you freak out, lets go over each of the tricky parts of
the code above.  First off, @data is not really being used at all in
this example.  I only included it in case you need to be able to refer
to the data in sequential order.  If you don't need that, you don't
need to build @data.  The next weird bit is probably

@[EMAIL PROTECTED] = split;

This is a hash slice*.  It is roughly equivalent to saying

my @list = split /\s+/, $_; #not quite the same thing as split with no
args, but close see split for more info**
$record{vlan} = $list[0];
$record{host} = $list[1];
$record{mac} = $list[2];
$record{port} = $list[3];

The next line that looks difficult is

push @{$data_by{$_}{$record{$_}}}, \%record for @fields;

This says "for every field type (e.g. vlan, host, mac, port) make an
entry in the top level of %data_by.  Then make an entry in that level
for this record's value in that field.  Finally, push onto the array
stored in that level the whole record."  It is building a hash of
hashes of arrays of hashes.  You may want to read more about complex
data structures*** and references****.

The other line that might give you trouble is

print "\t\t", join("\t", @[EMAIL PROTECTED]), "\n";

Here $record is a reference to what was originally in %record in the
loop that built the data structure.  This is just another way to write
the slice we used then.  When you have a hash you can say

@[EMAIL PROTECTED]

but when you have a hash reference you must say

@[EMAIL PROTECTED]

* http://perldoc.perl.org/perldata.html#Slices
** http://perldoc.perl.org/functions/split.html
*** http://perldoc.perl.org/perldsc.html
**** http://perldoc.perl.org/perlref.html
-- 
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to