Как преобразовать последовательность чисел в массиве к диапазону чисел

В JavaScript, как преобразовать последовательность чисел в массиве к диапазону чисел?

например. [2,3,4,5,10,18,19,20] к [2-5,10,18-20]

24
задан Peter Lang 16 February 2010 в 05:44
поделиться

8 ответов

 ; For all cells of the array
    ;if current cell = prev cell + 1 -> range continues
    ;if current cell != prev cell + 1 -> range ended

int[] x  = [2,3,4,5,10,18,19,20]
string output = '['+x[0]
bool range = false; --current range
for (int i = 1; i > x[].length; i++) {
  if (x[i+1] = [x]+1) {
    range = true;
  } else { //not sequential
  if range = true
     output = output || '-' 
  else
     output = output || ','
  output.append(x[i]','||x[i+1])
  range = false;
  } 

}

Что-то вроде этого.

0
ответ дан 28 November 2019 в 23:10
поделиться

Вот алгоритм, который я сделал некоторое время назад , первоначально написанный для C #, теперь я перенес его на JavaScript:

function getRanges(array) {
  var ranges = [], rstart, rend;
  for (var i = 0; i < array.length; i++) {
    rstart = array[i];
    rend = rstart;
    while (array[i + 1] - array[i] == 1) {
      rend = array[i + 1]; // increment the index if the numbers sequential
      i++;
    }
    ranges.push(rstart == rend ? rstart+'' : rstart + '-' + rend);
  }
  return ranges;
}

getRanges([2,3,4,5,10,18,19,20]);
// returns ["2-5", "10", "18-20"]
getRanges([1,2,3,5,7,9,10,11,12,14 ]);
// returns ["1-3", "5", "7", "9-12", "14"]
getRanges([1,2,3,4,5,6,7,8,9,10])
// returns ["1-10"]
28
ответ дан 28 November 2019 в 23:10
поделиться

Вы можете перебирать числа и смотреть, будет ли следующее число на 1 больше текущего. Итак, есть:

struct range {
    int start;
    int end;
} range;

где if array [i + 1] == array [i] +1; (где i - текущее наблюдаемое число) then диапазон. конец = массив [i + 1]; . Затем вы переходите к следующему i ; Если array [i + 1]! = Array [i] +1; , то range.end = array [i];

, вы можете сохранить диапазоны в векторе < диапазон> диапазоны;

распечатать было бы просто:

for(int i = 0; i < ranges.size(); i++) {
    range rng = (range)ranges.at(i);
    printf("[%i-%i]", rng.start, rng.end);
}
0
ответ дан 28 November 2019 в 23:10
поделиться

Просто получаю удовольствие от решения от CMS:

  function getRanges (array) {
    for (var ranges = [], rend, i = 0; i < array.length;) {
      ranges.push ((rend = array[i]) + ((function (rstart) {
        while (++rend === array[++i]);
        return --rend === rstart;
      })(rend) ? '' : '-' + rend)); 
    }
    return ranges;
  }
5
ответ дан 28 November 2019 в 23:10
поделиться

Вот мой взгляд на это ...

function getRanges(input) {

  //setup the return value
  var ret = [], ary, first, last;

  //copy and sort
  var ary = input.concat([]);
  ary.sort(function(a,b){
    return Number(a) - Number(b);
  });

  //iterate through the array
  for (var i=0; i<ary.length; i++) {
    //set the first and last value, to the current iteration
    first = last = ary[i];

    //while within the range, increment
    while (ary[i+1] == last+1) {
      last++;
      i++;
    }

    //push the current set into the return value
    ret.push(first == last ? first : first + "-" + last);
  }

  //return the response array.
  return ret;
}
1
ответ дан 28 November 2019 в 23:10
поделиться

Вот версия для Perl:

use strict;
use warnings;

my @numbers = (0,1,3,3,3,4,4,7,8,9,12, 14, 15, 19, 35, 35, 37, 38, 38, 39);
@numbers =  sort {$a <=> $b} @numbers ; # Make sure array is sorted.

# Add "infinity" to the end of the array.
$numbers[1+$#numbers] = undef ;

my @ranges = () ; # An array where the range strings are stored.

my $start_number = undef ;
my $last_number  = undef ;
foreach my $current_number (@numbers)
{
  if (!defined($start_number))
  {
    $start_number = $current_number ;
    $last_number  = $current_number ;
  }
  else
  {
    if (defined($current_number) && (($last_number + 1) >= $current_number))
    {
      $last_number = $current_number ;
      next ;
    }
    else
    {
      if ($start_number == $last_number)
      {
        push(@ranges, $start_number) ;
      } 
      else
      {
        push(@ranges, "$start_number-$last_number") ;
      }
      $start_number = $current_number ;
      $last_number  = $current_number ;
    }
  }
}

# Print the results
print join(", ", @ranges) . "\n" ; 
# Returns "0-1, 3-4, 7-9, 12, 14-15, 19, 35, 37-39"
1
ответ дан 28 November 2019 в 23:10
поделиться

Если вам просто нужна строка, представляющая диапазон, то вы найдете среднюю точку вашей последовательности, и это станет вашим средним значением (10 в вашем примере). Затем возьмите первый элемент в последовательности и элемент, который непосредственно предшествует средней точке, и постройте представление первой последовательности. Проделайте ту же процедуру, чтобы получить последний элемент и элемент, который следует сразу за средней точкой, и постройте представление последней последовательности.

// Provide initial sequence
var sequence = [1,2,3,4,5,6,7,8,9,10];
// Find midpoint
var midpoint = Math.ceil(sequence.length/2);
// Build first sequence from midpoint
var firstSequence = sequence[0] + "-" + sequence[midpoint-2];
// Build second sequence from midpoint
var lastSequence  = sequence[midpoint] + "-" + sequence[sequence.length-1];
// Place all new in array
var newArray = [firstSequence,midpoint,lastSequence];

alert(newArray.join(",")); // 1-4,5,6-10

Демонстрация онлайн: http://jsbin.com/uvahi/edit

1
ответ дан 28 November 2019 в 23:10
поделиться

Я как раз искал именно эту вещь. Мне нужна была версия PHP, поэтому я перенес решение CMS. Вот он, для тех, кто останавливается на этом вопросе и ищет то же самое:

function getRanges( $nums )
{
    $ranges = array();

    for ( $i = 0, $len = count($nums); $i < $len; $i++ )
    {
        $rStart = $nums[$i];
        $rEnd = $rStart;
        while ( isset($nums[$i+1]) && $nums[$i+1]-$nums[$i] == 1 )
            $rEnd = $nums[++$i];

        $ranges[] = $rStart == $rEnd ? $rStart : $rStart.'-'.$rEnd;
    }

    return $ranges;
}
5
ответ дан 28 November 2019 в 23:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: