File Coverage

blib/lib/List/Util/WeightedChoice.pm
Criterion Covered Total %
statement 38 39 97.4
branch 8 10 80.0
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 54 57 94.7


line stmt bran cond sub pod time code
1             package List::Util::WeightedChoice;
2              
3 1     1   12062 use 5.006000;
  1         4  
  1         40  
4 1     1   5 use strict;
  1         3  
  1         33  
5 1     1   6 use warnings;
  1         13  
  1         168  
6              
7 1     1   6 use Carp qw(croak);
  1         2  
  1         2068  
8             require Exporter;
9 1     1   2393 use AutoLoader qw(AUTOLOAD);
  1         3637  
  1         7  
10 1     1   1605 use Params::Validate qw(:all);
  1         21268  
  1         1726  
11              
12              
13             our @ISA = qw(Exporter);
14              
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18              
19             # This allows declaration use List::Util::WeightedChoice ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             our %EXPORT_TAGS = ( 'all' => [ qw(
23             choose_weighted
24             ) ] );
25              
26             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
27              
28             our @EXPORT = qw(
29            
30             );
31              
32             our $VERSION = '0.06';
33              
34              
35              
36             sub choose_weighted{
37 4     4 1 306 validate_pos(@_,
38             { type => ARRAYREF },
39             { type => CODEREF | ARRAYREF}
40             );
41              
42 4         15 my ($objects, $weightsArg ) = @_;
43 4 100       23 my $calcWeight = $weightsArg if 'CODE' eq ref $weightsArg;
44 4         4 my @weights; # fix wasteful of memory
45 4 100       10 if( $calcWeight){
46 2         4 @weights = map { $calcWeight->($_) } @$objects;
  6         27  
47             }
48             else{
49 2         6 @weights =@$weightsArg;
50 2 50       7 if ( @$objects != @weights ){
51 0         0 croak "given arefs of unequal lengths!";
52             }
53             }
54              
55 4         13 my @ranges = (); # actually upper bounds on ranges
56 4         5 my $left = 0;
57 4         8 for my $weight( @weights){
58 12 50       23 $weight = 0 if $weight < 0; # the world is hostile...
59 12         14 my $right = $left+$weight;
60 12         13 push @ranges, $right;
61 12         22 $left = $right;
62             }
63 4         48 my $weightIndex = rand $left;
64 4         15 for( my $i =0; $i< @$objects; $i++){
65 8         11 my $range = $ranges[$i];
66 8 100       43 return $objects->[$i] if $weightIndex < $range;
67             }
68             }
69              
70              
71             # Preloaded methods go here.
72              
73             # Autoload methods go after =cut, and are processed by the autosplit program.
74              
75             1;
76             __END__