Jason Normandin wrote: > Hey Group > > I am new to hashes, so please be kind : ) > > I am trying to create a hash of hash's with the following characteristics: > > 1. The outer hash has a unique key called $ELEMENT
Back off here. You haven't yet described the problem you are trying to solve, and you are already making wild guesses about the tools to be used for the problem. You get nowhere, and get there in a hurry, when you act begfore you have identified a goal. > > 2. The value of the outer hash is a key to the innner hash called $DATE > 3. The value of the inner hash is a value called $ERROR > > I need to loop through some data which has multipe $DATE and $ERROR entries > per $ELEMENT and add them to the $ELEMENT hash based on the $ELEMENT value. > > Eg. Element Fred would have multiple DATE entries. Each date would have one > error. > > I then need to iterate through the hash and display the element name( only > once if possible ), each timestamp and error. > > Ex. > > ELEMENT DATE ERROR > jason Jun 1, 2003 No Data > Jun 4,2003 No Response > July 1,2003 No Data > fred Jan 2, 2002 No Response > Jany 4,2002 Illegal value > .... > .. > > This is just a dummy example. The real error types range and are unique. > > Can anyone help with my constructing such a hash ? > > I tried the following, which sucessfully creates the outerhash, but only > populates one value for each date, error pair: > > $snmpErr{$ELEMENT}= > { > name => $ELEMENT, No need for this. You already have the significant information stored in the key. That redundancy will hold true for every single element in the list. > > date => $DATE, > error => $ERROR > }; Presuming that you are reading this, you should probably be assigning smething more like: $snmpErr{$element}->{ error_guid} = [$date, $error]; Unless, of course, you know for sure, that no person will ever make more than one error in a single day. > > I then loop through via: > > foreach my $entry (keys %snmpErr) > { > $el = $snmpErr{$entry}{name}; $snmpErr{$entry}->{'name'} was assigned the same way as the other two keys. Why are you accessing it differently? $snmpErr{$entry} is a hash reference, not a hash. If you do want a subsort by name, just skip the name key entirely, since it's reduncant. > $el = $entry; > $ts = $snmpErr{$entry}->{date}; > $er = $snmpErr{$entry}->{error}; > } > > How far off am I ? : ) > > Thanks for the help all !! > > - Jason I'd start by thinking about any one error. From you data, it sounds like the distinguishing characteristics are the element [Do you often refer to living beings as elements? That seems very, very sad. OTOH, if you simply give your machines human names, its sorta sweet], the date, and the error message. You indicated that you want to group by element, so lets not put that information in the structure used to hold any one error. You have achoice of two suitable structures here, and its a matter of taste. Using an array where the elements are alway added in the same order could work alright. Still you would have to remember that $error[0] is the date and $error[1] was the error string. Or was it the other way around? my $error = [$date, $description] creates a reference to an anonyous array with element ditinguished by their order. Note that you have to use a reference here. Whole arrays or hashes get flattened into simple lists when assigned to elements of multidimesional structures. The results are very ugly. I would recommend using a hash instead, for the sake of clarity. It is less efficient, but it is more important to be clear. my $error = { date => $name, description => $description } The file snippet you showed indicated that all the error for any element were already group by the element. That is convenient. You can make some use of that in the next layer, which should be an array. Since any element could have an arbitrary number of errors associated with it, and since there is no meaningful key to be associated with any element to distinguish it, an anonymous array is appropriate, IMHO. for this level of structure. my $elemental_errors = [ {date => $date[0], description => $description[0]}, {date => $date[1], description => $description[1]}, ... although you would not want to load it that way. Or maybe you would. If you are committing this to a database, this advice might change. You might then want to use the guid of the item in the "error" table as the key for each error item. On that case would want to make a hash. my $elemental_errors = { $db_primary_keys[0] => {date => $date[0], description => $description[0]}, $db_primary_keys[1] => {date => $date[1], description => $description[1]}, So we now need to find the appropriate type of collection to hold the elements. Each of these clearly does have a name, which, presuming that the names are guaranteed unique, a perfect call for a hash. my $errors = { 'Alex' => [{date => '1/1/2003', error => 'engaging in ultraviolence'}, {date => '10/31/2003', error => 'submittingly cravenly to dictates of society'}] 'Dim' => [... So if you put all this together, and assuming that you read from a file organized by element, we might have: use strict; use warnings; use Data::Dumper; my $log; open $log, 'errors.log' or die "Sorry, couldn't open the error log. $!"; my $errors = {}; my $error_line = <$log>; #we throw this first line away $error_line = <$log>; my $element; chomp $error_line; while ($error_line) { if ($error_line =~ /^\w/) { $error_line =~ /(.*?)\s+([A-Z][a-z]{2,3}\s+\d+,\s*\d+)\s+?\b(.+)\b/; $element = $1; $errors->{$element} = []; push @{$errors->{$element}}, trim_details($2, $3); } else { $error_line =~ /\s+([A-Z][a-z]{2,3}\s+\d+,\s*\d+)\s+?\b(.+)\b/; push @{$errors->{$element}}, trim_details($1, $2); } $error_line = <$log>; } sub trim_details { my ($date, $error) = @_; $date =~ s/\s+/ /g; $date =~ s/,\b/, /; return {date => $date, error => $error}; } print Dumper $errors; ^Z $VAR1 = { 'jason' => [ { 'date' => 'Jun 1, 2003', 'error' => 'No Data' }, { 'date' => 'Jun 4, 2003', 'error' => 'No Response' }, { 'date' => 'July 1, 2003', 'error' => 'No Data' } ], 'fred' => [ { 'date' => 'Jan 2, 2002', 'error' => 'No Response' }, { 'date' => 'Jany 4, 2002', 'error' => 'Illegal value' } ] }; HTH, Joseph -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]