List::Util - yeah, it was other monks who introduced me to this module. I've made good use of it since ;-)
Back to your question ... Let's say that the number we get is "5". Looking at this list, that should result in picking "baz". How do we do that? We look at the numbers: the first weight is one. So that would be a pick of 0. That's not it. So then the next option, 'bar', has a weight of 3. So that will cover picks 1-3. But we have 5, so that's not in range, either. Next option has a weight of 4 - numbers 4-7. We have 5. Got it.
That's the straight-forward approach. The convoluted approach reverses this. We start with the first option, and discover that it has a weight of 1. So, now we look at the number - if the number were 0, this would be a match. If the number were 1, it isn't. So we could simply check if $pick < $weight and return 1, otherwise we just subtract the weight from our pick, and check the next number. However, since we're in a block, not a sub, we need to be a bit more tricky. So, we do a bit of algebraic magic, and we come up with $pick - $weight < 0, and we still want to subtract the weight before going on to the next one. Finally, we just do the subtraction first, and let $pick < 0 be our boolean return from the block.
In reply to Re^5: Picking a random item through probability
by Tanktalus
in thread Picking a random item through probability
by muba
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |