如何从数组中生成连续的数字

How to Make Consecutive Numbers from an Array

我有一个这样的数组

[-2,4,5,6,7,8,10,11,15,16,17,18,21]

有谁知道如何使该数组的输出变成这样的整数

-2,4-8,10-11,15-18,21

输出会把连续的数变成一个数

这对我来说是新事物,如有任何帮助,我们将不胜感激,谢谢

下面我创建了一个函数,用于用包含其范围的字符串替换数组中的序列。一共有三个函数。

getConsectiveCount 将数组和索引作为参数,并获取之后连续数字的计数。

replaceFirstConsective 将采用数组并将仅替换数组中的第一个序列。

replaceAllConsectives 将替换数组中的所有序列。

const arr = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
const getConsectiveCount = (arr, index) => {
  let count = 0;
  for(let i = index; i < arr.length; i++){
    if(arr[i + 1] === arr[index] + (i - index) + 1){
      count++;
    }
  }
  return count;
}

console.log(getConsectiveCount(arr, 1));
const replaceFirstConsective = (arr) => {
  for(let i = 0; i < arr.length; i++){
    let count = getConsectiveCount(arr,i);
    if(count){
      
  return [...arr.slice(0, i), `${arr[i]}-${arr[i + count]}`, ...arr.slice(i + count + 1)]
    }
  }
  return arr;
  
}
const replaceAllConsectives = (arr) => {
  for(let i = 0; i < arr.length;i++){
    arr = replaceFirstConsective(arr)
  }
  return arr;
}

console.log(JSON.stringify(replaceAllConsectives(arr)))

const inp = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
let res = [];
for(let i=0;i<inp.length;i++){
        let b = inp[i];
    let j = i+1;
    while(j<inp.length){
        if(b+1 == inp[j]){
        b = inp[j++];
        continue;
      }
      break;
    }
    if(i == j-1){
     res.push(inp[i]);
     }
    else{
      res.push(inp[i]+"-"+inp[j-1]);
      i=j-1;
    } 
}
console.log(res);

如果有帮助请勾选。

我已经做到了:

const arr1 = [-2,4,5,6,7,8,10,11,15,16,17,18,21]

const arr2 = arr1.reduce((a,c,i,{[i+1]:nxt})=>
  {
  if (!a.s1) a.s1 = c.toString(10)
  if ( (c+1) !== nxt ) 
    {
    a.s1 += a.s2 ? `_${a.s2}` : ''
    a.r.push(a.s1)
    a.s1 = a.s2 = ''
    }
  else  a.s2 = nxt.toString(10)
 
  return (nxt===undefined) ? a.r : a
  },{r:[],s1:'',s2:''})


console.log(JSON.stringify( arr2 ))
.as-console-wrapper { max-height: 100% !important; top: 0; }

这是一个有趣的问题。我解决它的方法是遍历数组,然后从当前数中找到最后一个连续数的索引。我们可以将单个数字写入结果数组,也可以将范围字符串写入其中,然后从范围后的下一个数字继续。

function lastConsecutive(arr, start)
{    
    let ind = start;
    while(ind < arr.length && (arr[ind] + 1) == arr[ind + 1])
    {
        ind++;
    }

    return ind;
}

function consecCollapse(nums)
{
    let i = 0;
    const result = [];
    while (i < nums.length)
    {        
        let n = lastConsecutive(nums, i);
        result.push((n == i) ? nums[n]+"" : nums[i]+"-"+nums[n]);
        i = n + 1;
    }
    return result;
}

console.log(consecCollapse([-2,4,5,6,7,8,10,11,15,16,17,18,21]));

const arr = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
const _newArray = [];
let start = arr[0];
let end = start;
for(let i=1; i<=arr.length; i++) {
    let elem = arr[i];
    if (elem === end+1) {
        end = elem; // update the end value (range)
    }else {
        if (end !== start) {
            _newArray.push(`${start}-${end}`);
        } else {
            _newArray.push(start);
        }
        start = elem;
        end = start;
    }
}

console.log(_newArray.join(','))

如果排序数组具有唯一数字,这就是我用破折号找到数字范围的方法:

function findRange(arr) {
    const results = []
    for (let i = 0; i < arr.length; i++) {
        // only more than 2 consecutive numbers can be form a range
        if (arr[i + 1] === arr[i] + 1 && arr[i + 2] === arr[i] + 2) {
            // store the first number of a range
            results.push(arr[i])
            // loop until meet the next one is not consecutive
            while (arr[i] + 1 === arr[i + 1]) {
              i++
            }
            // store the last number of a range with '-' in between
            results[results.length - 1] = results[results.length - 1] + '-' + arr[i]
        } else {
            // if only 2 consecutive number or not consecutive at all
            results.push(arr[i])
        }
    }
    return results
}

console.log(findRange([1, 2, 3, 4, 6, 7, 8, 9]))
console.log(findRange([1, 2, 4, 6, 7, 8, 9]))
console.log(findRange([-2,4,5,6,7,8,10,11,15,16,17,18,21]))