从整数的排序数组创建字符串范围



我有以下排序的数字数组(它们可以重复,例如 21)

let a = [1,2,3,4,7,8,12,15,21,21,22,23]

并希望获得带有范围的字符串的以下(排序)数组

let r =["1-4","7-8","12","15","21-23"]

对于连续的数字 a,a+1,a+2,...,a+n=b w 必须创建字符串"a-b",例如对于 6,7,8,我们希望得到"6-8",对于"单独"数字,我们只想得到那个数字,例如,对于上面示例中的 12,我们得到"12"。

这是我的尝试,但我坚持了下来(并感到头痛)

let a = [1,2,3,6,7,8,12,15,21,21,22,23];
let right=a[0];
let left=a[0];
let result=[];
for(let i=1; i<a.length; i++) {
    for(let j=1; j<a.length; j++) {
      if(a[i]<a[j])result.push(`${a[i]}-${a[j]}`);
      
  }
}
console.log(JSON.stringify(result));

更新:

这是这个问题的"反转"

您可以将下一个预期值存储在闭包中并减少数组。

function getRanges(array) {
    return array.reduce((l => (r, v, i, a) => {
        if (l[1] > v) return r;
        r.push(l[1] === v
            ? (r.pop(), l.join('-'))
            : (l = [v, v]).slice(0, 1).toString()
        );
        l[1]++;
        return r;
    })([]), []);
}
console.log(getRanges([-3, -2, -1, 2]));
console.log(getRanges([1, 2, 3, 4, 7, 8, 12, 15, 21, 21, 22, 23]));

这应该为您完成。

const a = [1,2,3,4,7,8,12,15,21,21,22,23,27]
let min = a[0], last = a[0]
const result = a.reduce((arr, n, i) => {
  if(n - last > 1){
    if(min == last) arr.push(""+min)
    else arr.push([min, last].join("-"))
    
    min = n
  }
  
  if(i == a.length - 1) {
    if(min == n) arr.push(""+min)
    else arr.push([min, n].join("-"))
  }
  
  last = n
  
  return arr
}, [])
console.log(result)

另一种方式可能是

let a = [1,2,3,4,7,8,12,15,21,21,22,23]
let r = a.reduce((acc, val) => {
  const lastGroup = acc.pop() || [];
  const lastValue = lastGroup.slice(-1)[0];
  if (val - lastValue > 1) {
    return [...acc, lastGroup, [val]];    
  }
  return [...acc, [...lastGroup, val]];
}, []).map(group => {
  const first = group[0];
  const last = group[group.length-1];
  return first !== last ? `${first}-${last}` : `${first}`;
});
console.log(r)

你不需要两个循环,只要跟踪你开始组的时间:

let array = [1,2,3,4,7,8,12,15,21,21,22,23]
const groups = [];
let start = array[0];
array.push(NaN);
for(let index = 1; index < array.length; index++) {
  const value = array[index], previous = array[index - 1];
  if(value === previous + 1 || value === previous) 
     continue;
  if(start === previous) {
    groups.push("" + previous);
  } else {
    groups.push(start + "-" + previous);
  }
  start = value;
}
console.log(groups);

这也是我的答案(灵感来自其他答案)

let r = (a,c='-',f=a[0],g=[]) => (a.map((x,i,a,b=a[i+1]) =>
        b<=x+1 ? 0 : (g.push( f-x ? f+c+x : f+'' ),f=b) ),g);

let a = [1,2,3,4,7,8,12,15,21,21,22,23];
let b = [-7,-5,-4,-3,-1,0,1,3,4,5,8]; 
let r = (a,c='-',f=a[0],g=[]) => (a.map((x,i,a,b=a[i+1]) =>
        b<=x+1 ? 0 : (g.push( f-x ? f+c+x : f+'' ),f=b) ),g);
let J= JSON.stringify;
console.log(J(a) + ' -> ' + J(r(a)));
console.log(J(b) + ' -> ' + J(r(b,'..')));

说明:g=[] 包含结果,第一个范围元素是f=a[0],一开始我们检查下一个元素b=a[i+1]是否等于或小于当前元素 x 加 b<=x+1 一。如果 NO(这意味着范围结束或 i 是最后一个索引 - b=undefined),那么我们将范围推送到结果 g.push( f-x ? f+'-'+x : f+'' )(我们在这里检查 x 是否不等于 f 乘以 f-x -> f-x!=0 -> f!=x),在推送设置第一个范围元素f到下一个范围(元素 b 之后)。

最新更新