2015-04-30 3 views
0

я генерация списка номеров:Как преобразовать список чисел в список диапазонов последовательных чисел

[1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19] 

Обратите внимание, как некоторые номера отсутствуют (в данном случае, каждый пятый номер). Я хочу преобразовать последовательные числа в диапазоны, ограниченные тире.

В приведенном выше случае, я хотел бы выход быть

"1-4,6-9,11-14,16-20" 

Как я могу идти о решении этой проблемы?

+1

Что youtried? –

+0

Я выполнил многочисленные поисковые запросы Google, и я продолжаю сталкиваться с RegEx, чего я еще не изучил, но после краткого обзора его я не уверен на 100%, что это решение моей проблемы на основе примеров I продолжайте сталкиваться. Я столкнулся с одним решением, которое включало в себя многочисленные if else-выражения внутри цикла, которые генерировали числа, и идея была почти щелкает в моей голове, однако решение было написано на PHP, и попытка расшифровать и перевести на JS сделала только мои мозг больнее. По сути, я еще не пробовал, поскольку подход еще не нажал. – bdorrance

ответ

5
var convertToRanges = function (str) { 
    // split the string at the commas and map it to an array of ints 
    // NOTE: if you are passing an array, skip this step 
    var pieces = str.split(",").map(Number) 
    // ranges will be an array of arrays 
    // each inner array will have 2 dimensions, representing the start/end 
    // of a range 
    // we want to initialize our first range to pieces[0], pieces[0], 
    // or (only the first element) 
     , ranges = [[pieces[0], pieces[0]]] 
    // last index we accessed (so we know which range to update) 
     , lastIndex = 0; 

    for (var i = 1; i < pieces.length; i++) { 
     // if the current element is 1 away from the end of whichever range 
     // we're currently in 
     if (pieces[i] - ranges[lastIndex][1] === 1) { 
      // update the end of that range to be this number 
      ranges[lastIndex][1] = pieces[i]; 
     } else { 
      // otherwise, add a new range to ranges 
      ranges[++lastIndex] = [pieces[i], pieces[i]]; 
     } 
    } 
    return ranges; 
} 

Это возвращает массив массивов:

console.log(convertToRanges("1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19")); 
// -> [ [1, 4], [6, 9], [11, 14], [16, 19] ] 

Я оставлю вас, чтобы выяснить, как превратить это выглядеть "1-4,6-9,11-14,16-20"

Подсказка: используйте Array.prototype.map и Array.prototype.join

+0

Спасибо. Сейчас я буду работать над этим подходом. Я должен был заметить, что это на самом деле мой самый первый фрагмент JavaScript, который я написал, и это мой первый вопрос в Stackoverflow. Мой единственный предыдущий опыт работает через различные онлайн-курсы. «Диапазон» api - это недостающее звено, которое я не мог найти. Большое спасибо за Вашу помощь! – bdorrance

+0

@bdorrance, что вы подразумеваете под диапазоном '' api'? – royhowie

+0

@bdorrance, вероятно, вы видели переменные, объявленные следующим образом: 'var a = 1, b = 2, c = 3;'. Когда вы объявляете их по разным строкам, это (сейчас) считается хорошей практикой/условным обозначением для запятой на следующей строке. Это делается для [предотвращения неявных глобалов] (http://stackoverflow.com/questions/5786851/define-global-variable-in-a-javascript-function) (которые вы никогда не должны использовать). – royhowie

0

Решение возвращает завершенные строки и обрабатывает изолированные номера которые не являются частью целого ряда

function convert(input) { 
    var res = [], 
     arr = typeof input == 'string' ? input.split(',').map(Number) : input; 
    while (arr.length) { 
     var curr = arr.shift(), 
      lastIncIdx = null; 

     if (arr.length && curr == arr[0] - 1) { 
      var next = arr.length ? arr.reduce(function (last, curr, idx, arr) { 
       if (curr == last + 1) { 
        lastIncIdx = idx; 
        return curr; 
       } else { 
        return last; 
       } 
      }) : curr; 

      if (next != curr) { 
       arr.splice(0, lastIncIdx + 1); 
       res.push(curr + '-' + next) 
      } 
     } else { 
      res.push(curr) 
     } 
    } 
    return res.join(); 
} 

DEMO

Смежные вопросы