Splits an array into smaller arrays based on the total of elements. This is an extremely limited use sub I needed for a one off script but I thought someone else might possibly find it useful.
=pod
=head1 buckets
buckets (size=> N, els=> \@ARRAY ,opt[ ref_to=>\&CODE ] );
Given a size and an array reference, splits the array into an AoA
with each element being a reference to an array whose elements are les
+s than
C<size> in total. If an element is larger than C<size> it is placed in
+to a single
"bucket".
If the elements of the original array are more complex then numeric sc
+alars, you
can pass a code ref that returns access to the criteria element.
Example:
my @array = (10 ,9 , 15, 40, 67, 2, 35);
my @res = buckets(size=>30, els=>\@array);
\@res = [
[ 50 ],
[ 67 ],
[ 40 ],
[
15,
10
],
[
9,
2
]
];
Or with references..
my @array = ( ['foo',10 ], ['bar', 4 ], ['base', 18 ], ['foobar',5 ],
+ ) ;
my @res = buckets(size=>30, els=>\@array, ref_to=>sub { $_->[1] } );
It does not attempt to find the optimal set of elements. It simply sor
+ts the
values in reverse numeric order.
=cut
sub buckets {
my %args = @_;
die "missing size argument: " unless defined $args{size};
die "argument element is not an ARRAY reference: $args{els}"
unless UNIVERSAL::isa($args{els},'ARRAY');
die "argument ref_to is not a CODE reference: $args{ref_to}"
if defined $args{ref_to} and !UNIVERSAL::isa($args{r
+ef_to},'CODE');
return () unless @{$args{els}};
my @orig = @{$args{els}};
my @els = defined $args{ref_to} ? sort { $b->[0] <=> $a->[0] }
map { [ &{$args{ref_to}}, $_ ] }
+
@orig
: sort {$b <=> $a} @orig;
my ($size,@res) = (0);
local $_;
{
$_ = shift @els;
$_ = $_->[1] if $args{ref_to};
my $el = $args{ref_to} ? &{$args{ref_to}} : $_ ;
$size = push(@res,[]) && 0 if $size + $el > $args{size} or $el
+> $args{size} ;
$size+=$el;
push @{$res[-1]}, $_;
redo if @els;
}
@res;
}
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.