Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Combine range of numbers.

by the_0ne (Pilgrim)
on Jan 31, 2004 at 04:27 UTC ( #325495=perlquestion: print w/replies, xml ) Need Help??
the_0ne has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I know my title is vague, but I thought I'd let the actual content speak for itself. Here's what I want to do. I want to take this...


and turn it into this


I do have code and it works, however it just doesn't look perlish to me. I've always thought of regexes as basicly "can do anything with text". I tried a few and they just failed miserably. Here is my code...
#! /usr/bin/perl use strict; my $pages = "1,2,3,5,6,7,10,12,13,14,15"; my @pages_arr = split ',', $pages; my (@return_arr, $next_one, $lower_bound, $upper_bound); @return_arr = (); $next_one = ''; $lower_bound = ''; $upper_bound = ''; for (my $x = 0; $x < scalar(@pages_arr); $x++) { $next_one = $pages_arr[$x]; if ($x == 0) { $lower_bound = $upper_bound = $next_one; } elsif ($next_one == ($upper_bound + 1)) { $upper_bound = $next_one; if ($x == (scalar(@pages_arr) - 1)) { push @return_arr, "${lower_bound}-${upper_bound}"; } } elsif ($next_one != ($upper_bound + 1)) { if ($lower_bound == $upper_bound) { push @return_arr, $lower_bound; } else { push @return_arr, "${lower_bound}-${upper_bound}"; } $lower_bound = $upper_bound = $next_one; if ($x == (scalar(@pages_arr) - 1)) { push @return_arr, $next_one; + } } } my $return_var = join ',', @return_arr; print "return_var: ${return_var}\n";
It just looks so un-perlish. It does work and so far I haven't found a combination that breaks it. (The reason I say that is because this is part of a larger script that formats the input from the user like that. So, the numbers will always be in order and comma-delimited before it gets to that chunk of code.) However, it just looks like way too much code to do something so trivial. I won't ask if there is a better way, because Perl wouldn't be Perl if there wasn't. I'd just like to see what other Monks would do with this problem.

Thanks Monks.

Replies are listed 'Best First'.
Re: Combine range of numbers.
by cees (Curate) on Jan 31, 2004 at 04:46 UTC

    This was a question on the perl quiz of the week that ran for a few months last year. Question #6 asks exactly what you are looking for.

    Here is MJDs summary.

    The shortest solution was provided by Andreas Koenig:

    use Set::IntSpan; # CPAN rules :-) use strict; sub expand_number_list { my $run = shift; my $set = Set::IntSpan->new($run); $set->elements; }

    Here is a list of everyone else's submisions.

    Update: Silly me, I included Andreas' answer for expand_number_list by mistake! Here is the one you are looking for:

    use Set::IntSpan; # CPAN rules :-) use strict; sub format_number_list { my(@n) = @_; my $set = Set::IntSpan->new(join ",", @n); my $run = $set->run_list; $run =~ s/,/, /g; # give them the spaces $run; }
      Thanks cees, I'll check those out.
Re: Combine range of numbers.
by japhy (Canon) on Jan 31, 2004 at 04:36 UTC
    I direct you to a node by me. It solves the problem with a regex.

    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Dude (mouth drops open) that is amazing... the_0ne bows humbly to japhy
Re: Combine range of numbers.
by jweed (Chaplain) on Jan 31, 2004 at 04:34 UTC
      Thanks jweed, my mind keeps thinking "print range", since we are using this for pages in documents, that I didn't search for number range or sequential numbers. :( Thanks for the reply.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://325495]
Approved by jweed
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2018-05-21 18:00 GMT
Find Nodes?
    Voting Booth?