2016-12-31 17 views
0

私は範囲値[1,35]を持つ配列を持っています。その後、私は[2,5], [8,9]ように、他の範囲を有する二番目の配列、等与えられた範囲からいくつかの範囲を除外します

に今は最初からこれらの範囲を減算し、 [1-1]2-5が取り出されるように)、次いで次[6,7]、次いで[10,35]など値を取得する必要があります。

基本的には、2番目の配列の範囲を取り出して最初の配列から削除したいと考えています。

どうすればいいですか?

+1

、問題/質問されますか? – Andreas

答えて

1

以下のES6機能を使用できます。

第1引数に複数の範囲を指定することができ、範囲が重複していないとみなします。関数の戻り値は、最初の引数に基づいた配列ですが、2番目の引数で指定された範囲は削除されています。あなたは、各パートの範囲の範囲をチェックして簡単な方法を使用することができます

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; }

関連する問題