in reply to Converting a growing hash into an array of arrays
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.)
And here's the demo and testing portionsub 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
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
|
|---|