如何将数组中的数字序列转换为数字范围

gok*_*kul 25 javascript range sequence

在javascript中如何将数组中的数字序列转换为数字范围?

例如.[2,3,4,5,10,18,19,20][2-5,10,18-20]

CMS*_*CMS 28

这是我前一段时间制作的算法,最初是为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"]
Run Code Online (Sandbox Code Playgroud)

  • 建议先对值进行排序,这样就可以处理混合值,如:[1,3,2,6,5,7] (8认同)

HBP*_*HBP 5

只是玩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;
  }
Run Code Online (Sandbox Code Playgroud)


Dis*_*oat 5

我只是在寻找这个确切的事情.我需要一个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;
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*eur 5

我发现这个答案很有用,但需要一个Python版本:

def GroupRanges(items):
  """Yields 2-tuples of (start, end) ranges from a sequence of numbers.

  Args:
    items: an iterable of numbers, sorted ascendingly and without duplicates.

  Yields:
    2-tuples of (start, end) ranges.  start and end will be the same
    for ranges of 1 number
  """
  myiter = iter(items)
  start = myiter.next()
  end = start
  for num in myiter:
    if num == end + 1:
      end = num
    else:
      yield (start, end)
      start = num
      end = num
  yield (start, end)


numbers = [1, 2, 3, 5, 6, 7, 8, 9, 10, 20]
assert [(1, 3), (5, 10), (20, 20)] == list(GroupRanges(numbers))
assert [(1, 1)] == list(GroupRanges([1]))
assert [(1, 10)] == list(GroupRanges([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
Run Code Online (Sandbox Code Playgroud)


Sam*_*son 0

如果您只需要一个表示范围的字符串,那么您将找到序列的中点,这将成为您的中间值(在示例中为 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
Run Code Online (Sandbox Code Playgroud)

在线演示: http: //jsbin.com/uvahi/edit

  • 既然数字 1-10 是按顺序出现的,没有缺失,那么输出不是 1-10 吗? (6认同)