Search code examples
javascriptarraysjavascript-objectsoverlapping-matches

Remove and update overlapping indexes in array of object in javascript


I have an array of object with overlap indexes.

[
  //1st object
  {
    start: 3,
    end: 10
  },
  //2nd object
  {
    start: 5,
    end: 8
  },
  //3rd object
  {
    start: 11,
    end: 30
  },
  //4th object
  {
    start: 0,
    end: 4
  }
]

I want to create array new array by modifing and removing some of the overlapping object i.e case1:- remove if any object falls completely in an interval, i.e. second object can be removed, as it falls in first object case2:- if any object falls partially within the interval, i want to update the indexes. so that all the objects can be different

final result will look like below.

[
  //I increased 1st object by 2 as 4th object's end index is 4. I increased (end of 4th - start of 1st) + 1
  {
    start: 5,
    end: 12
  },
  //I removed 2nd object
  // I changed the 3rd object by 2 because it's overlapping with the newly created `{start:5, end:12}` object
  {
    start: 13,
    end: 32
  },
  // No change in 4th object.
  {
    start: 0,
    end: 4
  }
]

Any suggestion how can I solve this problem. I tried the below approach to modify the array.

const updateArray = arr => {
  let sortArr = arr.sort((a,b)=> a.start - b.start || a.end - b.end);
  let newArr = sortArr.reduce((r,a) =>{
    let obj = r[r.length - 1] || {};
      if (obj.start <= a.start && a.start <= obj.end) {
        if (obj.end < a.end) {
          a.start = obj.end + 1;
        } else {
          obj.start = a.end + 1;
        }
      }
      return r.concat(a);
  },[]);
  return newArr;
}

Solution

  • I am assuming that a sorted output would be fine (since you were using one). If so, then the script below will solve it.

    Script:

    function modifyArray(array) {
      var prevEnd;
      array = array.sort((x,y) => x.start - y.start);
    
      for(i = 0; i < array.length; i++) {  
        if(!i) { 
          prevEnd = array[i].end;
          continue;
        }
        if(array[i].start < prevEnd && array[i].end > prevEnd) { 
          diff = prevEnd + 1 - array[i].start;
          array[i].start += diff;
          array[i].end += diff; 
          prevEnd = array[i].end;
        }
        else if(array[i].start > prevEnd) 
          continue;
        else 
          array.splice(i--, 1);
      }
      return array;
    }
    
    function test() {
      let array1 = [ { start: 3, end: 10 },
                    { start: 5, end: 8 },
                    { start: 11, end: 30 },
                    { start: 0, end: 4 } ];
      let array2 = [{start: 10, end: 12}, {start:17, end: 19}]
    
      console.log(modifyArray(array1))
      console.log(modifyArray(array2))
    }
    

    Output:

    output1