javascriptjqueryd3.jsleft-joinanti-join

How to do an anti-join (select of left join) in Javascript/jQuery/D3


From an array of objects in JavaScript (D3) I need to remove every object for which a certain attribute equals another certain attribute in another array of objects, i.e. do an anti-join, i.e. a select of left columns of left join rows with introduced nulls.

anti-join

I do it with two loops but it's quite slow.

for (var i = 0; i < data1.length; i++) {
  for (var j = 0; j < data2.length; j++) {
    if (data2[j].attr3 == data1[i].attr4) {
      data2.splice(j,1);
    }
  }
}

data1.length is ~2k and data2.length is ~10k.

What is a faster method with JavaScript or jQuery or D3?

This has approximately been asked at Joins in Javascript but the solutions use external libraries.


Solution

  • You need a fast lookup for the values that exist in data1, so make a map using an object:

    var map = {};
    for (var i = 0; i < data1.length; i++) {
      map[data1[i].attr4] = 1;
    }
    

    Then you can loop throught the items in data2 and filter them:

    var result = [];
    for (i = 0; i < data2.length; i++) {
      if (!(data2[i].attr3 in map)) {
        result.push(data2[i]);
      }
    }