Вывести массив коротким образом в String

114
23 октября 2019, 11:10

Есть массив,числа это типа номера маршруток на данном улице.Числа идут только на возрастание и по порядку.

[1,3,4,5,6,8,10,12,13,14,17]

Нужно чтобы те числа которые последовательны друг другу по 1 -

(3,4,5,6)(12,13,14)

были написаны таким образом -

(3-6)(12-14)

И в итоге получать такой String -

1,3-6,8,10,12-14,17

Еще примеры массивов -

[10,11,12] 10-12

[1,2,3,4,5,9] 1-5,9

У меня неполноценный код.

function solution(x) { 
  let y = []; 
  let min; 
  let max; 
  for (var i = 0; i < x.length; i++) { 
    if (x[i] - x[i - 1] == 1) { 
      y.push(x[i]) 
    } 
  } 
  y.unshift(y[0] - 1); 
  min = y[0]; 
  max = y[y.length - 1]; 
  y = [min, max]; 
  y = y.toString().split(",").join("-"); 
  return y 
} 
console.log(solution([1, 3, 4, 5, 6, 8])) //3-6 
console.log(solution([1, 3, 4, 5, 6, 8, 10, 11, 12])) //3-12

Answer 1

Много разного можно придумать, например так:

function print(arr) { 
  // для пустого массива проще сразу вернуть результат 
  if (!arr.length) {   
    return ''; 
  } 
   
  return arr 
    .sort((a, b) => a - b)  // сортируем как числа (если нужно) 
    // итерируемся по массиву, накапливаем результат 
    // learn.javascript.ru/array-iteration#reduce-reduceright 
    .reduce((intervals, value, index) => { 
      // первый элемент мы уже обработали - см. ниже 
      if (!index) {  
        return intervals; 
      } 
 
      // intervals - массив непрерывных интервалов, 
      // берём последний элемент последнего массива 
      const interval = intervals[intervals.length - 1]; 
      const last = interval[interval.length - 1]; 
 
      // текущий элемент входит в последний интервал? 
      if (value - last === 1) {   
        interval.push(value); 
      } else {  // создаём новый (следующий) интервал 
        intervals.push([value]); 
      } 
 
      return intervals;  // reduce требует возращать накопитель 
    }, [  // начальное значение для intervals — первый интервал 
      [arr[0]] 
    ]) 
    // итерируемся, превращаем каждый интервал 
    // в его строковое представление 
    .map(interval => { 
      if (interval.length > 1) {  // диапазон 
        return `${interval[0]}-${interval[interval.length - 1]}`; 
      } else {  // в интервале всего один элемент  
        return String(interval[0]); 
      } 
    }) 
    .join();  // склеиваем через запятые 
} 
console.log(print([1, 3, 4, 5, 6, 8, 10, 11, 12]))

Answer 2

Что попроще:

UPD: исправил с запятыми

var list = [ 
    [], 
    [1], 
    [2, 3], 
    [3, 4, 5], 
    [1, 2, 4, 5, 6, 8, 10, 11, 12], 
    [1, 3, 4, 5, 6, 8, 10, 11, 12, 15], 
    [-23, -20, -21, -22, 5, 7, 8, 4, 3, 55, 54] // [ -23, -22, -21, -20, 3, 4, 5, 7, 8, 54, 55 ] 
]; 
 
function solution (array) { 
 
    // ! сортировка в обратном порядке, смотри ниже while 
    var arr = array.slice(0).sort((a, b) => b - a); 
 
    var l = arr.length; 
    if (!l) { 
        return ''; 
    } 
 
    var currentRange = 0; 
    var arrRange = [[]]; 
    var current; 
 
    // ! смотри выше сортировка 
    while (--l) { 
        current = arr[l]; 
        arrRange[currentRange].push(current); 
        if (current + 1 !== arr[l - 1]) { 
            currentRange = arrRange.push([]) - 1; 
        } 
    } 
    current = arr[l]; 
    arrRange[currentRange].push(current); 
 
    // смотри чтоб понятно было 
    console.log('arrRange: ', JSON.stringify(arrRange)); 
 
    return arrRange.reduce((a, v) => { 
        v.length > 2 ? a.push(v[0] + '-' + v[v.length - 1]) : a.push(v.join()) 
        return a; 
    }, []).join(/*default = ','*/); 
 
} 
 
list.forEach(a => console.log('solution: ', solution(a)));

READ ALSO
Сортировка базы данных по нажитию на кнопки

Сортировка базы данных по нажитию на кнопки

У меня вот есть база данных в формате json

122
Как сделать отмену действия?

Как сделать отмену действия?

В чём ошибка моего кода? Первая ветвь работает нормально, как сделать чтобы при повторном нажатии заработала и вторая ветвь?

130
Размещение блоков в конце секции

Размещение блоков в конце секции

Есть 3 блокаКак разместить их внизу секции home например? Они в воздухе, не могу их спустить

120
Объединение нескольких html в Thymeleaf

Объединение нескольких html в Thymeleaf

Как объединить несколько html файлов в Thymeleaf? Я реализовывал данный код через php с помощью include_once "headerhtml";, но в thymeleaf подобной конструкции не нашел

101