in reply to Using map to convert an array into a hash of array of arrays

rjoost:

I'm going to agree with moritz. If you're having that much trouble figuring it out, then how will you be able to debug it or modify it three months from now? It's far too easy to make code that's hard to maintain.

I'd suggest making a subroutine that will chop up the line and return a hash reference, then you can use map to call your subroutine:

my %sorted_msgs = map { $_[5], $_[0] } sort { Date_Cmp($a->[1], $b->[1]) } map { crunchit($_) } @matched_lines; sub crunchit { ... }

By the way, since you're calling your hash %sorted_msgs, shouldn't your sort be on $_[5] rather than $_[1], or perhaps your hash key should be $_[1]? Otherwise, you won't actually have a sorted list of messages, would you? (Or are you simply trying to ensure that later entries overlay earlier entries?)

...roboticus

Replies are listed 'Best First'.
Re^2: Using map to convert an array into a hash of array of arrays
by rjoost (Novice) on Aug 11, 2010 at 05:29 UTC
    Ok, Roboticus and Moritz, thanks for the tips. I get it now ;-) I'm really getting into the more functional aspects of Perl's map as a transformative helper!

    my %alertlog_mapper = map { $_->[1] => [ $_->[3], $_->[4], $_->[6], $_ +->[2], $_->[5] ] } sort { Date_Cmp($a->[2], $b->[2]) } map { my @logline = (); my ($msg_id, $timestring, $min, $sec, $secs, $secs_before, + $secs_after); @logline = split(/\s+/, $_, 5); $timestring = $logline[0] . ' ' . $logline[1]; $min = substr($logline[1], 3, 2); $sec = substr($logline[1], 6, 2); $secs = $min * 60 + $sec; $secs_before = $secs - 5; $secs_after = $secs +5; #my @lookup_alerts = & $msg_id = $logline[3]; [ $_, $logline[3], ParseDate($timestring), $logline[0], $l +ogline[1], $logline[2], $logline[4] ]; } @gmsgs;

    I'll keep up with the perldocs and keep working on perl data structures, as time permits.

      I'm revisiting to undertand maps more...been reading the perldocs, almost there, but could use some clarification.

      If I've got Dumper output like this:

      $VAR1 = [ '2100', [ '2010-08-12', '12:23:56', 'INFO', '2100', 'some stuff, REPA0.prm: Executing DDL operation.' ], '2100', [ '2010-08-12', '12:23:56', 'INFO', '2100', 'some output, REP.prm: DDL operation is of default scope. +' ],

      With a data structure of an array of arrays, where the first "element" is 2100 in this example,

      I'd like to convert this into a Hash of array of arrays where 2100 is the hash key to an array of arrays.

      %alertlog = map { $_->[0] => [ $_->[2], $_->[3], $_->[4], $_->[5], $_ +->[6] ]; } sort { Date_Cmp($a->[1], $b->[1]) } map { chomp; @loglines = split(/\s+/, $_, 5); $timestring = $loglines[0] . ' ' . $loglines[1]; [ $loglines[3], (ParseDate($timestring), $loglines[0], $lo +glines[1], $loglines[2], $loglines[3], $loglines[4]) ]; } @messages;

      This creates a hash of arrays just fine, but it flattens out the array of arrays.

      In the original array of arrays, the $_->[0] referred to above is always the first element in an array of arrays.

      Below, the "2100" key should show, as it's hash value, an array of arrays....... And likewise for any "key" which has one or more arrays as its resultant value.

      DUMP OF %alertlog from check_alertlog(): $VAR1 = { '109' => [ '2010-08-13', '17:42:58', 'ERROR', '109', 'some stuff, .... SQL <UPDAT...' ], '190' => [ '2010-08-13', '17:42:58', 'ERROR', '190', 'another message ' ], '2100' => [ '2010-08-12', '21:18:53', 'INFO', '2100', 'another message...' ] };

      So, from the array which was passed, and, from which, using map, I'm trying to create a hash of arrays of arrays, the map I've got so far, creates a hash of arrays just fine, BUT it doesn't do a hash of arrays of arrays properly...

      If I make the map output an array of arrays, it works for that just fine and outputs, e.g.,

      $VAR1 = [ [ '2100', '2010-08-12', '15:34:37', 'INFO', '2100', 'bunch of info: Executing operation.' ], [ '2100', '2010-08-12', '15:34:37', 'INFO', '2100', 'bunch of info: operation is of unmapped scope.' ], [ '2100', '2010-08-12', '15:34:37', 'INFO', '2100', 'bunch of info, REP.p: Executing operation.' ],
      If I could take that output, in the map, and make "2100" the hash key to an array of arrays, that's what I am trying to do.. under time pressure so will go back to the docs tonight and keep trying as time and life permit.

        ...and "miles to go before I sleep ..."

        I'll close this request because I no longer am trying to use map to transform a basic array of lines into a hash of arrays of arrays because I don't have time to explain what I'm trying to do in greater detail and I also changed the first, original data structure I was using into a hash of hash of arrays and much happier.