If you've got a lot of data to work with, you really want to do your incrementing updates with a hash, otherwise you will be scanning through every element of the $data[0] array every time you want to increment. The number of compares goes up with the square of the number of log entries, which can get expensive. (The solutions by jmcada and holli, however, are nice and clear, and are efficient if the number of elements in the sub-arrays don't get too long. I'd go with that approach if your logs are short.)

The sub below uses an external hash of references to the elements of $data[1], called %data_refs_hash. Using that hash you can do the increment directly. You only need to scan through the array when you're adding a new key (and you only need to do that if you're keeping the keys in order, if not, leave out the while() scan and just push the new values on the end instead of splicing them.)

sub IncrData { my $key = shift; if (exists $data_refs_hash{$key} ) { # if there's a hash entry ${$data_refs_hash{$key}}++; # increment it } else { # otherwise, find a spot and put one in my $idx = 0; my $endIdx = scalar(@{$data[0]}); while ($idx < $endIdx && $data[0][$idx] < $key) { $idx++; } splice(@{$data[0]},$idx,0,$key); splice(@{$data[1]},$idx,0,1); $data_refs_hash{$key} = \$data[1][$idx]; } # if you need to update the sort each time, then do @{$data[2]} = sort { $a <=> $b } @{$data[1]}; # but you shouldn't update it until you're going to use it, # since it's expensive to sort for every increment } # IncrData
And here's the demo and testing portion
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) ] ); # create a hash of refs to the things you want to updated. # This is only needed for the example, so that we can # use the ininialized array above. Normally, the hash is just updated # each time a new element is added to the arrays in IcrData(). for $idx (0..$#{$data[0]} ) { $data_refs_hash{$data[0][$idx]} = \$data[1][$idx]; } print join(", ", @{$data[1]}), "\n"; IncrData("3.4"); IncrData("3.5"); IncrData("9.5"); IncrData("1.1"); IncrData("9.5"); print "\n"; print join(", ", @{$data[0]}), "\n"; print join(", ", @{$data[1]}), "\n"; print join(", ", @{$data[2]}), "\n"; #produces 1.1, 1.6, 2.2, 3.4, 3.5, 3.6, 5.4, 6.2, 7.1, 8.1, 9.0, 9.5 1, 1, 2, 6, 1, 6, 3, 15, 4, 3, 4, 2 1, 1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 15
Updated: Reformatted code to move testing into "readmore" and revised non-code portion

In reply to Re: Converting a growing hash into an array of arrays by rodion
in thread Converting a growing hash into an array of arrays by madbombX

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.