in reply to How Not to Alter Hash in HoA while Counting Array

I don't think your code is doing what you think it is doing?

I added a couple of print statements to a sllightly reworked version of your count_support_mismatch() routine:

sub count_support_mismatch { my( $hashref, $arref, $d ) = @_; my $counter = 0; foreach my $key ( keys %{ $hashref } ) { my $ar = $hashref->{$key}; my @match_list; print join( '|', @{ $ar } ) . "\n" . join( '|', @$arref ) . "\ +n"; foreach my $elem ( @{ $ar } ) { foreach my $q ( @$arref ) { print "Hamming '$elem' <=> '$q'\n"; my $dist = hd( $elem, $q ); if( $dist <= $d ) { #print "$q - $_\n"; push @match_list, $elem; } shift @{ $ar }; # Part that alter hash } } $counter++ if @match_list; } return $counter; }

And got this output:

P:\test>459758 GGAA|GGGG|TTTT GGGG|GGGG Hamming 'GGAA' <=> 'GGGG' Hamming 'GGAA' <=> 'GGGG' GGGA|GTTT|GGGG GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' GGGG|AAAA|GGGG GGGG|GGGG Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' GGGA|GCGG|GTTT GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' Support = 3

which indicates that you are only comparing the first element of each hash value array against each of the elements from your query array. Is this your intent?

If so, then there is no purpose in the middle of your 3 nested loops and the shifting. You need only hardcode the first element into the call to hd() and omit the middle loop to achieve the same goal and avoid modifying the arrays:

sub count_support_mismatch { my( $hashref, $arref, $d ) = @_; my $counter = 0; foreach my $key ( keys %{ $hashref } ) { my $ar = $hashref->{$key}; my @match_list; print join( '|', @{ $ar } ) . "\n" . join( '|', @$arref ) . "\ +n"; foreach my $q ( @$arref ) { print "Hamming '$ar->[ 0 ]' <=> '$q'\n"; my $dist = hd( $ar->[ 0 ], $q ); if( $dist <= $d ) { #print "$q - $_\n"; push @match_list, $ar->[ 0 ]; } } $counter++ if @match_list; } return $counter; }

which produces the same results:

P:\test>459758 GGAA|GGGG|TTTT GGGG|GGGG Hamming 'GGAA' <=> 'GGGG' Hamming 'GGAA' <=> 'GGGG' GGGA|GTTT|GGGG GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' GGGG|AAAA|GGGG GGGG|GGGG Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' GGGA|GCGG|GTTT GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' Support = 3

However, if your intent is to compare each element of the hash element arrays against eachelement of the query array, then you need only omit the shift @{ $ar }; to produce this output:

P:\test>459758 GGAA|GGGG|TTTT GGGG|GGGG Hamming 'GGAA' <=> 'GGGG' Hamming 'GGAA' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' Hamming 'TTTT' <=> 'GGGG' Hamming 'TTTT' <=> 'GGGG' GGGA|GTTT|GGGG GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' Hamming 'GTTT' <=> 'GGGG' Hamming 'GTTT' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' GGGG|AAAA|GGGG GGGG|GGGG Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' Hamming 'AAAA' <=> 'GGGG' Hamming 'AAAA' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' Hamming 'GGGG' <=> 'GGGG' GGGA|GCGG|GTTT GGGG|GGGG Hamming 'GGGA' <=> 'GGGG' Hamming 'GGGA' <=> 'GGGG' Hamming 'GCGG' <=> 'GGGG' Hamming 'GCGG' <=> 'GGGG' Hamming 'GTTT' <=> 'GGGG' Hamming 'GTTT' <=> 'GGGG' Support = 4

Which avoids modifying the hash element arrays, but that gives a different results?

Another possibility is that you want to compare the 2 elements of the query array against the first two elements (0 & 1) of the hash element arrays, then against (1 & 2) and then (2 & 3) (if 3 existed) etc.

That's a little more complex to code and would require using indices into the hash element array and shifting the start position after the execution of the inner loop. That seems to be what you are trying to do, but if you are, you have misplaced the shift. It should be outside the inner loop not inside.

That's my best guess. It's now over to you to indicate whether any of my guesses are correct :)


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.