Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge arrays with overlapping values

Tags:

javascript

Im using Node.js. (...and underscore.js)

Consider this data structure

var numbers = [
  [10, 20]
  [30, 40]
  [40, 50]
  [45, 70]
  ... //Possibly more arrays (always contains two numbers)
]

numbers contain arrays that always contain number pairs. Think of these number pairs as "start" and "end". I want a function that takes numbers as argument, and loop trough its content, and if the "start" number of a pair overlap the "end" number of previous pair, these arrays is merged into one. For example this:

var numbers = [
  [10, 20]
  [19, 40]
  [40, 60]
  [70, 80]
]

Becomes this:

var numbers = [
  [10, 60] // First, second and third array is merged because of overlapping . 
  [70, 80]
]

Actually, I already have written a function for this that works fine, but feels a bit clunky.

I'm curious if some javascript wizard can dazzle me with a super elegant solution =).

like image 452
Anders Östman Avatar asked Oct 15 '14 19:10

Anders Östman


People also ask

How do you combine overlapping intervals?

A simple approach is to start from the first interval and compare it with all other intervals for overlapping, if it overlaps with any other interval, then remove the other interval from the list and merge the other into the first interval. Repeat the same steps for the remaining intervals after the first.

How do I combine multiple arrays into one?

To merge elements from one array to another, we must first iterate(loop) through all the array elements. In the loop, we will retrieve each element from an array and insert(using the array push() method) to another array. Now, we can call the merge() function and pass two arrays as the arguments for merging.

How do you merge two arrays using the spread operator?

To combine two or more arrays, you can either use the functional method []. concat(arr1, arr2) or the spread operator [...arr1,...arr2]. The merging outcome is kept in a new array, making these methods immutable.

Does array concat remove duplicates?

concat() can be used to merge multiple arrays together. But, it does not remove duplicates.


2 Answers

let arr = [
  [1, 3],
  [2, 6],
  [5, 10],
  [15, 18],
  [18, 6],
];

const mergeoverlapping = (arr) => {
  if (arr.length < 2) return intervals;
  arr.sort((a, b) => a[0] - b[0]);
  let top = 0;
  let down = arr.length - 1;
  let left = 0;
  let temp = [];
  let right = arr[0].length - 1;
  let result = [];
  while (top + 1 <= down) {
    if (arr[top][right] >= arr[top + 1][left]) {
      arr[top + 1][left] = arr[top][left];
      temp = [arr[top + 1][left], arr[top + 1][right]];
    } else {
      result.push(temp);
      temp = arr[top + 1];
    }
    top++;
  }
  result.push(temp);
  console.log(result);
};

console.log(mergeoverlapping(arr));
like image 170
ritik bhatt Avatar answered Sep 28 '22 00:09

ritik bhatt


Create an empty "result" array. Loop over the ranges array and either change the last item of the result or add the current range to it.

function merge(ranges) {
    var result = [], last;

    ranges.forEach(function (r) {
        if (!last || r[0] > last[1])
            result.push(last = r);
        else if (r[1] > last[1])
            last[1] = r[1];
    });

    return result;
}

r = [[10, 20], [19, 40], [40, 60], [70, 80]];
document.write(JSON.stringify(merge(r)));

This assumes that the source array is sorted, if it's not always the case, sort it before merging:

ranges.sort(function(a, b) { return a[0]-b[0] || a[1]-b[1] });
like image 32
georg Avatar answered Sep 28 '22 01:09

georg