You're definitely making things far too difficult for yourself. This isn't a comprehensive review, since I have to go to work soon, but
The first thing I noticed is that your code is difficult to read. Several factors contribute to this:
It turns out that the last two points are related. Any time you have code like this:
if (some condition) { ... some code ... $precords{$product_key}{"total_count"}++; # BOTH BRANCHES ... more code ... next; # BOTH BRANCHES } else { ... some code ... $precords{$product_key}{"total_count"}++; # BOTH BRANCHES ... more code ... next; # BOTH BRANCHES }
See those lines labelled 'BOTH BRANCHES'? Since it's the same code, and nothing else in the 'more code' chunks affect those lines in both branches, you can move those statements to a more convenient location, like this:
$precords{$product_key}{"total_count"}++; if (some condition) { ... some code ... ... more code ... } else { ... some code ... ... more code ... } next;
I moved the 'next' statement until after the if/then statement, since we need to be sure that we execute the code. I put the other statement before the if/then statement because nothing in the if/then statement used that value.
You want to avoid duplicating code, because it makes the code harder to read:
Now let's take a look at your 'next' statements. Generally, they're used for special cases, but in your code, they're used so often that anyone making a change to your code will have to read and re-read the code frequently to see what it's doing. It can make the code pretty difficult to read.
By repeatedly moving code duplicated in both branches of your if/then statements, your code boils down to something like this:
for { if (value == '1') { ... do stuff ... next; } if (value == '0') { ... do stuff ... next; } ... do nothing ... }
And since the value isn't changing in any of the code in your loop, the next statements don't do anything at all, so you could simplify it a little more to:
for { if (value == '1') { ... do stuff ... } elsif (value == '0') { ... do stuff ... } }
Note: I changed the if to elsif to let the programmer know that you can't execute both conditional blocks. In your original code, if you changed something in the first block to turn value to '0', then suddenly your program would start always executing the code in the second if statement, too!
Finally, using == with strings is a recipe for bugs. If you want to compare numbers use ==, for strings use 'eq'. So statements like:
if ($comboHashRef{$key}->[0] == '0')
should be changed to either:
if ($comboHashRef{$key}->[0] == 0)
if you want to compare the value as a number, or:
if ($comboHashRef{$key}->[0] eq '0')
if you want to compare it as a string. If you're reading the records as strings from a file and parsing it, I'd suggest comparing it as a string.
I wanted to go over some more stuff, like comments and variable names, but I ran out of time. Before I started this post, I noticed that others were already offering some comments, so I'll leave further comments to others...
...roboticus
When your only tool is a hammer, all problems look like your thumb.
In reply to Re: Optimise Sub, make hash unique based on values in array
by roboticus
in thread Optimise Sub, make hash unique based on values in array
by anomilie
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |