Very interesting, and potentially very, very useful. It might also be useful to have the reverse function, compacting a list of numbers into a list containing ranges.
The code below seems to do this, with the caveats that:
With that in mind, here is my contribution:
sub compactRanges { # # @pieces contains the list of numbers # %parts will contain a compact form, such that $start..$end # is represented as $parts{$start} = $end # $seperator contains the character(s) placed between the # values # %wrap_negatives contains a flag indicated if negative # values should be wrapped in some way, and the leading # and trailing values if so # my (@pieces) = @_; my $seperator = '..'; my %wrap_negatives = ( 'flag' => 1, 'leading' => '[', 'trailing' => ']' ); my (%parts); @pieces = sort { $a <=> $b } @pieces; { my ($i); my ($recent); $recent = $parts{$i} = $i = shift (@pieces); while (@pieces) { $i = shift (@pieces); $recent = $i if ( $i - 1 > $parts{$recent} ); $parts{$recent} = $i; } } foreach my $k ( sort { $a <=> $b } keys(%parts) ) { my $str = ( ( $wrap_negatives{'flag'} ) and ( $k < 0 ) ? $wrap_negatives{'leading'} : '' ) . $k . ( ( $wrap_negatives{'flag'} ) and ( $k < 0 ) ? $wrap_negatives{'trailing'} : '' ); $str .= $seperator . ( ( $wrap_negatives{'flag'} ) and ( $parts{$k} < 0 ) ? $wrap_negatives{'leading'} : '' ) . $parts{$k} . ( ( $wrap_negatives{'flag'} ) and ( $parts{$k} < 0 ) ? $wrap_negatives{'trailing'} : '' ) if ( $parts{$k} != $k ); push ( @pieces, $str ); } return (@pieces); }
In reply to Re: Expand Ranges in Lists of Numbers
by atcroft
in thread Expand Ranges in Lists of Numbers
by The Mad Hatter
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |