Bobo Wieland <[EMAIL PROTECTED]> wrote:

> I have a textfield wich allows any number of integers seperated with
> " ", "," or "-"...
> 
> I need this input to be formated in two steps:
> First into a sequence of numbers into an array, lowest first...
> Second to the correct form of the initial input...
> 
> Example:
> 
> User input: "1,3, 3-6, 8" (string)
> First step: 1,3,4,5,6,8 (array)
> second step: "1,3-6,8" (string)

There are many ways to do this (as always :) ...

Do you really need the fully expanded array in step one, considering
it might get quite big?

Anyway, you can easily replace input ranges by expanded enumerations
with preg_replace:

  $input = preg_replace('= (\d+) \s* - \s* (\d+) =ex',
                        'implode(",", range($1,$2))',
                        $input);

>From there, next step is to transform this list of numbers into an array
and normalize it, eliminating duplicates and sorting.
If you're really dealing with integers only, a funny and efficient way
to eliminate duplicates is to flip the array, because any array key can
exist only once:

  $keys = array_keys( array_flip( split('[ ,]+', $input) ) );
  sort($keys);

For the second step, merging consecutive numbers into a range, just do
what you would do with paper and pencil:  start with first number,
step to next one and look, if it belongs to the previous range or starts
a new one.  Write a dash only for real ranges with more than a single
number:

  $start = $old = $keys[0]; $output = "$start";
  foreach($keys as $value) {
     if ($value > $old+1) // new range begins
     {
        if ($old<>$start) { $output .= "-$old"; }
        $start = $value; $output .= ",$start";
     }
     $old = $value;
  }
  if ($old<>$start) { $output .= "-$old"; }

HTH,
  Martin


-- 
PHP Windows Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to