2017-02-02 2 views
1

Я нашел похожие вопросы, но утвержденные ответы не работают для моей проблемы.Объединить перекрывающиеся объекты с интервальными свойствами в массиве с javascript

У меня есть вход: массив объектов диапазона каждый из которых содержит:

  • start: Целое число, начало диапазона,
  • end: Целое число, конец диапазона.

Выход должен быть:

Массив неперекрывающихся объектов, охватывающих диапазон тот же диапазон (ы) в качестве входных данных заказанного от наименьшего до наибольшего начала старта. Два диапазона не перекрываются, если:

  • range1.start <= range2.start и
  • range1.end >= range2.start

Входной сигнал:

[ 
    { start: 8, end: 10 }, 
    { start: 5, end: 7 }, 
    { start: 9, end: 12 }, 
    { start: 2, end: 6 }, 
] 

выход:

[ 
    { start: 2, end: 7 }, 
    { start: 8, end: 12 } 
] 

Как я уже говорил, я попытался применить решения в Интернете для слияния интервалов перекрытия, но они не выполняют эту работу.

спасибо.

ответ

0

Вы можете отсортировать массив по start и и перебрать отсортированный массив с проверкой диапазонов, если они перекрываются.

var data = [{ start: 8, end: 10 }, { start: 5, end: 7 }, { start: 9, end: 12 }, { start: 2, end: 6 }], 
 
    result = data 
 
     .sort(function (a, b) { return a.start - b.start || a.end - b.end; }) 
 
     .reduce(function (r, a) { 
 
      var last = r[r.length - 1] || []; 
 
      if (last.start <= a.start && a.start <= last.end) { 
 
       if (last.end < a.end) { 
 
        last.end = a.end; 
 
       } 
 
       return r; 
 
      } 
 
      return r.concat(a); 
 
     }, []); 
 

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

0

var ranges = [ 
 
    { start: 8, end: 10 }, 
 
    { start: 5, end: 7 }, 
 
    { start: 9, end: 12 }, 
 
    { start: 2, end: 6 } 
 
]; 
 

 

 
function merge(ranges) { 
 
    // first, sort the ranges 
 
    ranges.sort((a, b) => a.start - b.start); 
 
    
 
    // take two ranges, and merges them together 
 
    var mergeFn = (a, b) => ({start: Math.min(a.start, b.start), end: Math.max(a.end, b.end)}); 
 
    
 
    // check if two ranges overlap 
 
    var overlapFn = (a, b) => (b.start <= a.end); 
 
    
 
    // make current the first item of the array (start the array from 1 to not check the first item against itself) 
 
    var current = ranges[0]; 
 
    var result = []; 
 
    for(var i = 1; i < ranges.length; i++) { 
 
    if(overlapFn(current, ranges[i])) // if the current range overlapping with this range 
 
     current = mergeFn(current, ranges[i]); // merge them into the current range 
 
    else { // if not 
 
     result.push(current); // add the current accumulated range as result 
 
     current = ranges[i]; // start accumulating another one from this range 
 
    } 
 
    } 
 
    result.push(current); // add the last result 
 

 
    return result; 
 
} 
 

 
console.log(merge(ranges));

+0

Спасибо, Ибрагим. По какой-то причине предоставленный вами код не работает для меня (a и b не могут быть распознаны валидатором на странице, над которой я работаю), но я вижу, что здесь работает ваш код. Я использовал код Нины, и это сработало. Благодарю. –

+0

Добро пожаловать! Возможно, ваш браузер не поддерживает ** Функции стрелок ** (если вы используете код для использования браузером). –

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