[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [FWP] Formatting integer sets with ranges



my $list = '1,2,3,5,6,8,10';
my %hash;
my ($start, $last);
for (split ",", $list) {
    $start = $_ unless (defined $last and $_ == $last+1);
    $hash{$start} = $last = $_;
}
print join ",", map {$_ == $h{$_} ? $_ : "$_-$h{$_}"} sort {$a <=> $b}
keys %hash;

==>
1-3,5-6,8,10


The reverse (expanding the range list) is much more compact:
my $list = '1-3,5-6,8,10';
print join ',', map { m/(\d+)\-(\d+)/ ?  ($1..$2) : $_; } split ",",
$list;

==>
1,2,3,5,6,8,10


/prakash

Yitzchak Scott-Thoennes wrote:
> 
> I had to write a throwaway script to (among other things) print a
> sorted array of integers like 1,2,3,5,6,8,10 as a list of ranges like
> 1-3,5-6,8,10.  I remembered that there was a module to do this (it is
> Set::IntSpan) but I didn't want to take the time to search, download,
> install, and figure it out.  So after a couple minutes I came up with
> this:
> 
>         $pre = '';
>         while ($nxt = shift @issues) {
>             print $pre, $nxt;
>             if (($issues[0] || 0) == $nxt+1) {
>                 $nxt = shift @issues while ($issues[0] || 0) == $nxt+1;
>                 print "-$nxt";
>             }
>             $pre = ',';
>         }
>         print "\n";
> 
> I'll never need the script again, but it seems like there should be a
> somewhat simpler way to do this (along the lines of "print map ...").
> Any takers?
> 
> ==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
> ==== Send email to <fwp-request@technofile.org> with message _body_
> ====   unsubscribe

==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe