2016-12-31 2 views
0

У меня есть массив с диапазоном значений [1,35]. Тогда во втором массиве у меня есть другие диапазоны, как [2,5], [8,9] и т.д.Исключить несколько диапазонов от заданного диапазона

Теперь мне нужно вычесть эти диапазоны от первого, и получить значение, как [1-1] (как 2-5 вынимается), то следующим [6,7], а затем [10,35].

Так что в основном я хочу взять диапазоны из второго массива и удалить их из первого.

Как это сделать?

+1

И проблема/вопрос заключается? – Andreas

ответ

1

Вы можете использовать функцию ES6 ниже.

Он позволяет указать более одного диапазона в первом аргументе и предполагает, что он не имеет перекрывающихся диапазонов. Возвращаемое значение функции представляет собой массив, основанный на первом аргументе, но с диапазонами, указанными во втором аргументе, удаленным из него. Исходные массивы не мутировал в процессе:

function subtractRanges(a, b) { 
 
    // Take deep copy of a and sort it 
 
    a = a.map(x => [...x]).sort((x, y) => x[0] - y[0]); 
 
    // Take shallow copy of b and sort it 
 
    b = [...b].sort((x, y) => x[0] - y[0]); 
 

 
    var c = [], i = 0, j = 0; 
 
    while (i < a.length && j < b.length) { 
 
     var x = a[i], y = b[j]; 
 
     if (y[0] > x[0]) { 
 
      c.push([x[0], Math.min(y[0]-1, x[1])]); 
 
      if (y[1] < x[1]) { 
 
       x[0] = y[1]+1; 
 
       j++; 
 
      } else { 
 
       i++; 
 
      } 
 
     } else { 
 
      if (y[1] >= x[1]) { 
 
       i++; 
 
      } else { 
 
       if (y[1] >= x[0]) { 
 
        x[0] = y[1]+1; 
 
       } 
 
       j++; 
 
      } 
 
     } 
 
    } 
 
    // Add remainder of a, and return 
 
    return [...c, ...a.slice(i)]; 
 
} 
 

 
// Sample input 
 
var a = [ [1,35] ]; 
 
var b = [ [2,5], [8,9] ]; 
 

 
// Get result 
 
var result = subtractRanges(a, b) 
 

 
// Output result 
 
console.log(JSON.stringify(result));

+0

Это просто отлично! благодаря –

1

Вы можете использовать прямой вперед подход с проверкой диапазонов для каждого диапазона деталей. Он проверяет все возможные комбинации неперекрывающихся частей.

Это предложение работает с несортированными данными.

  ----------------     [ 9, 24] given interval, denotes as r 
    0000000001111111111222222222233333333334 
    123456789interval result   rules     return 
1   ----------------     [ 9, 24] none    i[0]===r[0]&&i[0]===r[0] none 
2    -------      [17, 23] [ 9, 16][24, 24] i[0]>r[0]&&i[1]<r[1]  [r[0],i[0]-1][i[1]+1,[r[1]]] 
3      ----------   [21, 30] [ 9, 20]   i[0]>r[0]&&i[0]<r[1]  [r[0],i[0]-1] 
4  --------        [ 5, 12] [13, 24]   i[1]>r[0]&&i[1]<r[1]  [i[1]+1,r[1]] 
5 ----          [ 1, 4] [ 9, 24]   i[1]<r[0]    r 
6         ----- [33, 37] [ 9, 24]   i[0]>r[1]    r 

function minus(r, a) { 
 
    var newR = []; 
 
    r.forEach(function (b) { 
 
     function push(t) { if (t[0] <= t[1]) { newR.push(t); } } 
 
     var temp = b.slice(); 
 
     if (a[0] === b[0] && a[1] === b[1]) { // 1 
 
      return; 
 
     } 
 
     if (a[0] > b[0] && a[1] < b[1]) { // 2 
 
      push([b[0], a[0] - 1]); 
 
      push([a[1] + 1, b[1]]); 
 
      return; 
 
     } 
 
     if (a[0] > b[0] && a[0] < b[1]) { // 3 
 
      temp[1] = a[0] - 1; 
 
     } 
 
     if (a[1] < b[1] && a[1] > b[0]) { // 4 
 
      temp[0] = a[1] + 1; 
 
     } 
 
     push(temp); 
 
    }); 
 
    return newR; 
 
} 
 

 
var ranges = [[1, 35]], 
 
    values = [[2, 5], [8, 9]], 
 
    result = values.reduce(minus, ranges); 
 

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

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