I tried to Super Search this, and I posted it in the Chatterbox, but I got directed here. This is really about finding the most elegant solution to a problem that suggests several ugly answers to me.
I have an N X M matrix that gives an output value for a pair of input values, say $x and $y. Each row of the matrix represents a range of values (disjoint from the others) that $x might fall into. Similarly for columns and $y. Thus, each matrix entry corresponds to the pair of intervals that contain $x and $y.
The most obvious way to deal with this is to create nested conditionals or a bunch of && conditionals that account for $x and $y, but that's unspeakably ugly and takes N*M conditional statements.
Less ugly is making a multi-dimensional hash, keyed by interval ID (e.g. Interval 1, Interval 2...), and then just setting up conditionals to return the right pair of IDs for $x and $y. That reduces the problem to N+M conditionals, but that's still a lot.
I thought about trying to find a way to transform $x and $y into their interval IDs, but the interval boundaries are floats and the first and last intervals are <some_value and >some_other_value, which makes that transformation harder.
I was taught to avoid a long sequence of conditionals, so I have to wonder: Is there a more elegant solution to this? Perhaps a module? Or should I just banish N+M conditionals to a subroutine at the bottom?
Thanks in advance,
Hays
Update:I like jdporter's solution for making the conditionals prettier, but it still involves a bunch of conditionals (unless I misunderstand). I don't have current code, since I'm looking for the best approach, but as per Grandfather's request, here's what code might look like that corresponds to the two approaches I've described:
Here's the solution most obvious to me (and least elegant):
if ($x<1) { if ($y<2.5) { $z=4; } elsif ($y>=2.5 && $y<3.5) { $z=6; } elsif..... } elsif ($x>=1 && $x<3.3) { if ($y<2.5) { $z=3 }......
And here's the solution that reduces it to N+M conditionals:
if ($x<1) { $xkey=1; } elsif ($x>=1 && $x<3.3) { $xkey=2; }... if ($y<2.5) { $ykey=1; } elsif ($y>=2.5 && $y<3.5) { $ykey=2; }... $z=$hash{$xkey}{$ykey};
What else would help?
Update 2: Thanks, nevyn!
In reply to Getting around nested conditionals by hgolden
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |