0

I would like to compare two arrays in jquery and return a new array of all the elements that do not match. so if I build a function like so:

function (parent, child) {}

I should compare child to parent and return a new array of all the elements in child that do not match parent. an example would be

parent = ['apple', 'banana'];
child = ['fruit'];

compare child to parent and get back and array: ['fruit'] as fruit is not in parent. I looked for methods to do this and saw this solution but I am not sure if this is what I want or not.

Community
  • 1
  • 1
user3379926
  • 3,855
  • 6
  • 24
  • 42
  • the operation you want to perform is called "array difference", look it up and you'll find many implementations – omma2289 Jun 11 '14 at 23:05

2 Answers2

2

You might want to look at Underscore.js (http://underscorejs.org/#difference), which has a function just for that. It returns the values from array that are not present in the other arrays.

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

To justify the use of yet another library: you might find tons of other useful utilities there ;)

oley
  • 339
  • 2
  • 4
  • I am actually using underscore js as I am using backbone. I never thought to look there. Thanks – user3379926 Jun 11 '14 at 23:18
  • @user3379926 I did not think the performance of underscore's difference is so bad, it's just a **little** better than the simple jQuery solution `diff = $(child).not(parent).get()` while it is much less efficient compared with the lookup solution (which I've made). Here is the test http://jsperf.com/lookup-vs-not2 (the first is lookup solution, the second is jQuery solution while the last is underscore solution). – King King Jun 11 '14 at 23:42
1

Be careful, using the keyword 'parent' may have unexpected side effects. In the version of Chrome I'm using, it seems to refer to Window.

Vanilla JavaScript solution, quick and easy:

var findDifference = function (elder, sibling) {

  var difference = [];

  for(var i = 0; i < sibling.length; i++){
    if(elder.indexOf(sibling[i]) < 0){
      difference.push(sibling[i]);
    }
  }
  return difference;
};


var elder = ['apple', 'banana'];
var sibling = ['fruit'];

findDifference(elder, sibling); // => ['fruit']
LexJacobs
  • 2,483
  • 15
  • 21
  • 1
    at least this is even better than using `_difference` and the jquery method with `.not()`, however it's still not fast as using look-up, see this test http://jsperf.com/lookup-vs-not2/2 .It's just fast when the parent's size has several items. – King King Jun 11 '14 at 23:57
  • 1
    @KingKing, great jsperf. At scale, the indexOf will underperform since it has to do array traversal for each lookup. The JavaScript Object is based on a hash table, so lookup is achieved in constant time. As you mentioned, for small arrays, either will do, but the look-up method is best at scale, as you demonstrated. – LexJacobs Jun 13 '14 at 00:58