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