in reply to Converting a growing hash into an array of arrays

splice?
use Data::Dumper; my @data = ( ["1.6","2.2","3.4","3.6","5.4","6.2","7.1", "8.1", "9.0"], [ 1, 2, 5, 6, 3, 15, 4, 3, 4], [ sort { $a <=> $b } (1, 2, 5, 6, 3, 15, 4, 3, 4) ] ); splice(@{$data[0]}, 1, 0, "2.1"); splice(@{$data[1]}, 1, 0, 7); $data[2] = [sort { $a <=> $b } @{$data[1]}]; print Dumper(\@data);

Replies are listed 'Best First'.
Re^2: Converting a growing hash into an array of arrays
by madbombX (Hermit) on Jul 14, 2006 at 17:17 UTC
    I think I should have been a little more specific. Once I get a new message coming in and it comes through the log, I have to increment the message count for a specific hit size by one. Therefore, if I have 3 messages that are 2.1 (the hash section would look like: $hits{"2.1"} = 3). Then when the new message comes in with a hit count of 2.1, then $hits{"2.1"} = 4. I know how to do this with a hash ($hits{"2.1"}++), but is there a way to do this with that multi-dimensional array I have listed above? I know splice will work for the one array($data[0]), but I need to adjust its corresponding value in the subsequent arrays.

    Thanks.

    Eric

      If I'm understanding this correctly, you need to increment the value in the second sub array based on the value found in the corresponding position on the first sub array. If so, this is probably a little over-thinking it, but it should work:
      my @data = ( ["1.6","2.2","3.4","3.6","5.4","6.2","7.1", "8.1", "9.0"], [ 1, 2, 5, 6, 3, 15, 4, 3, 4], [ sort { $a <=> $b } (1, 2, 5, 6, 3, 15, 4, 3, 4) ] ); print join(", ", @{$data[1]}), "\n"; map { $data[1]->[$_]++ if $data[0]->[$_] =~ /3.4/ } 0..$#{$data[0]}; print join(", ", @{$data[1]}), "\n"; --(0)> perl test.pl 1, 2, 5, 6, 3, 15, 4, 3, 4 1, 2, 6, 6, 3, 15, 4, 3, 4
        or less magical
        my @data = ... xadd( \@data, "3.4", 1); sub xadd { my $data = shift; my $elem = shift; my $incr = shift || 1; for ( 0..$#{$data} ) { $data->[1]->[$_] += $incr, $i = 1, last if $data->[0]->[$_] eq $elem; } unless ( $i ) { push @{$data->[0]}, $elem; push @{$data->[1]}, $incr; $data->[2] = [ sort { $a <=> $b } @{$data->[1]}; } # comment this line out if you don't # need to re-sort the 3rd array $data->[2] = [ sort { $a <=> $b } @{$data->[1]}; }
        Update: After posting I read that the OP needs that the solution works with an empty array. I added the edge case.


        holli, /regexed monk/
        That doesn't seem to work. When the program first begins to run, @data is empty and therefore generates errors with the join (since there is no data to be joined yet). Regardless, with the map statement above, nothing seems to get added to either of the arrays $data[0] or $data[1]. Note: I have been replacing (in this case) the 3.4 with $total because that's the variable name that holds the value of the hits that needs to be added or incremented within the array.

        Thanks.

        Eric

      Eric,

      I just don't understand why you are change the easy way with hash to a hard way with array ? Do you have problem with performance ? Is it about the hash size ?

      I don't know how long will be your array/hash, but if it's going to be large, RDD would be a good solution (or other kind of database).

      Solli Moreira Honorio
      Sao Paulo - Brazil