http://www.perlmonks.org?node_id=618960

in reply to removing the goto

redo LABEL is the answer to your question, but here are a couple of "better" ways to select \$maxclients unique elements from a bag (@weighteddiv).

This approach has the advantage of being simple, but it is relatively slow for large datasets and does not preserve the order in which the numbers were picked:

```my @weighteddiv = (('1234') x 7, ('9876') x 42, ('1123') x 13);
my %selected;
my \$maxclients = 2;

until (keys %selected == \$maxclients or @weighteddiv == 0) {
my \$i = rand(+@weighteddiv);  # Not \$#
my \$pluck = splice @weighteddiv, \$i, 1;
++\$selected{\$pluck};
}

my @selected = keys %selected;
print "Selected: @selected\n";

You can preserve the order with a little more code in the loop to create @selected incrementally:

```  if (++\$selected{\$pluck} == 1) {
push @selected, \$pluck;
}

Finally, a complicated but efficient solution involving probabilities:

```my @weighteddiv = (('1234') x 7, ('9876') x 42, ('1123') x 13);
my @selected;
my \$maxclients = 2;

my %occurrence;
foreach (@weighteddiv) {
\$occurrence{\$_}++;
}

my \$total = @weighteddiv;
until (@selected == \$maxclients or keys %occurrence == 0) {
my \$i = rand(\$total);
keys %occurrence;  # reset hash iterator
while (my (\$value, \$count) = each %occurrence) {
if (\$i < \$count) {
push @selected, \$value;
delete \$occurrence{\$value};
\$total -= \$count;
last;
}
\$i -= \$count;
}
}

print "Selected: @selected\n";