如何将一个整数数组“汇总”到一个带有范围的字符串?

时间:2015-09-16 13:45:26

标签: javascript arrays algorithm

假设您输入了Array=[1,2,3,5,7,9,10,11,12,15]

输出应为1-3,5,7,9-12,15

我正在寻找有关我的尝试和其他可能解决方案的反馈。 继承了我在javascript中的尝试:

var min = 0;
var max = -1;

function summarize(array) {
    var sumString = "";
    var prevVal = -1;

    array.forEach(function(currVal, index) {
        if (index > 0) {
            prevVal = array[index - 1];
        }
        if (index === 0) {
            min = currVal;
            max = currVal;
        } else if (currVal - prevVal === 1) {
            max = currVal;
        } else if (min !== max && max !== -1) {
            sumString += min + "-" + max + (index < array.length - 1 ? "," : "");
            min = currVal;
            max = -1;
        } else {
            sumString += min + (index < array.length - 1 ? "," : "");
        }

        if (index === array.length - 1) {
            if (max === -1) {
                sumString += "," + min;
            } else {
                sumString += min + "-" + max;
            }
        }
    });
    return sumString;
}

5 个答案:

答案 0 :(得分:2)

这是一个稍短的实现:

var i = 0, prev, arr = [1,2,3,5,7,9,10,11,12,15], out = [];
for(i=0; i<arr.length; prev = arr[i], i++) {

    // if the current number is not prev+1, append it to out
    // Note that we are adding it as a string, to ensure that 
    // subsequent calls to `split()` (see else part) works
    if(prev !== arr[i] - 1) out.push(String(arr[i]));

    // if the current number is prev+1, modify the last value
    // in out to reflect it in the RHS of - (hyphen)
    else out[out.length - 1] = [out[out.length - 1].split('-')[0], String(arr[i])].join('-');
}

// out => ["1-3", "5", "7", "9-12", "15"]

答案 1 :(得分:1)

如果不是,则第一步使用破折号分隔序号和逗号。第二步用getStringExtra()替换-#-

-

对于像var X = [1,2,3,5,7,9,10,11,12,15]; var S = '' + X[0]; for (var i = 1; i < X.length; i++) { S += (X[i] == X[i - 1] + 1)? '-': ','; S += X[i]; } while (/-[0-9]+-/.test(S)) S = S.replace(/-[0-9]+-/g, '-'); alert(S); 这样的序列会输出1,2,5,6,这可能不是您要查找的内容,因此可选的第三步是将1-2,5-6替换为#-#+1 ,即恢复逗号:

#,#+1

答案 2 :(得分:1)

升序中正数的另一种可能解决方案。它具有Array.prototype.reduce

var array = [1, 2, 3, 5, 7, 9, 10, 11, 12, 15, 23, 24],
    result = [];

array.reduce(function (r, a) {			
    result.push(r + 1 - a ? String(a) : result.pop().split('-')[0] + '-' + String(a));
    return a;
}, array[0]);		
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

答案 3 :(得分:0)

另一种可能的解决方案:

var points = [1,2,3,5,6,31,7,9,10,11,12,15];
points.sort(function(a, b){return a-b}); //sort array in asc
var resultArr=[];
var max; var min;
for(i=0;i<points.length;i++) //loop
{
    if(i==0)
    {
        min=points[i]; //lowest number in arr
        max=points[i]+1; //assign next value
    }
    else
    {
        if(max==points[i]) //if value matches continue
            max=points[i]+1;
        else //next value is not an incremental one so push it to result arr
        {
            max=max-1;
            resultArr.push(min+(min!=max? "-"+ max :""));
            min=points[i];
            max=points[i]+1;
        }
        if(i==points.length-1) //last element of the arr so push it to result arr
        {
            max=max-1;
            resultArr.push(min+(min!=max? "-"+ max :""));
        }

     }
}
alert(resultArr);

答案 4 :(得分:0)

我最近遇到了这个问题,经过一番反思,我注意到了3种不同的转换:(1)组连续数; (2)将组转换为表示范围的字符串; (3)在逗号上加入范围字符串。

function summarizeRange(items) {
  const sorted = items.slice(0).sort((a, b) => a - b);

  return sorted
    .slice(1)
    .reduce((range, item) => {
      const rangedIndex = range.reduce((ranged, rangedCollection, index) =>
        rangedCollection.indexOf(item - 1) > -1 ? index : ranged,
        -1
      );

      if (rangedIndex > -1) {
        range[rangedIndex] = range[rangedIndex].concat(item);

        return range;
      }

      return range.concat([
        [item]
      ]);
    }, [
      [sorted[0]]
    ])
    .map(range => range.length > 1 ?
      '' + range[0] + '-' + range[range.length - 1] :
      '' + range[0]
    )
    .join(',');
}

console.log(summarizeRange([0,3,2,6,19,20,22,21,1]));