2

i have a couple arrays in my javascript code (i'm using knockout js too) and i want to get a single array that contains only the common objects of all the arrays.

My code is something like this:

Array1 = [{a: 1, b: 'something'}, {a: 2, b: 'something1'},{a: 3, b: 'something3'}];

Array2 = [{a: 3, b: 'something3'}, {a: 1, b: 'something'}, {a: 4, b: 'something4'}]

Array2 = [{a: 3, b: 'something3'}, {a: 1, b: 'something'}, {a: 5, b: 'something5'}]

So, from this arrays i want the common of all into one single array, so the result would be like this:

Array4 = [{a: 1, b: 'something'}, {a: 3, b: 'something3'}]

I have to mention that the Array1, Array2 and Array3 are inside another array like this:

Array0 = [Array1, Array2, Array3];

I hope you can help me with this, thank you!

Phoenix_uy
  • 3,173
  • 9
  • 53
  • 100
  • You say "common of all", but then you include something3 in the result while is only in 2 of the arrays. Is this a typo or do you want to add something if it is in 2 of the arrays? – Smern Apr 01 '13 at 12:49
  • Oh.. im sorry, thats an error.. im correcting now, thank you for that! – Phoenix_uy Apr 01 '13 at 12:51
  • Are you interested in doing a deep compare of the objects? Is `{a:1, b: "something"}` the *same referenced object* each time, or *separate objects* with the same properties? – apsillers Apr 01 '13 at 12:51
  • Possible duplicate? [Simplest code for array intersection in javascript](http://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript) (but this isn't a jQuery solution -- I don't know if jQuery could make this job any easier than in POJS) – apsillers Apr 01 '13 at 12:52
  • The comparation could be only by the 'a' property of the object. – Phoenix_uy Apr 01 '13 at 12:54
  • I dont want to get the resulting array with duplicates :) – Phoenix_uy Apr 01 '13 at 12:56
  • Take a look at [underscore.js](http://underscorejs.org/) A reduce function in JS should do the work if you try hard, but underscore will make it easier. – naugtur Apr 01 '13 at 12:50

2 Answers2

5

For example:

Array1 = [{a: 1, b: 'something'}, {a: 2, b: 'something1'},{a: 3, b: 'something3'}];
Array2 = [{a: 3, b: 'something3'}, {a: 1, b: 'something'}, {a: 4, b: 'something4'}]
Array3 = [{a: 3, b: 'something3'}, {a: 1, b: 'something'}, {a: 5, b: 'something5'}]

all = [Array1, Array2, Array3]

objects = {}
counter = {}

all.map(function(ary, n) {
    ary.map(function(obj) {
        var key = JSON.stringify(obj);
        objects[key] = obj;
        counter[key] = (counter[key] || 0) | (1 << n);
    })
})

intersection = []
Object.keys(counter).map(function(key) {
    if(counter[key] == (1 << all.length) - 1)
        intersection.push(objects[key]);
})

console.log(intersection)

The idea is to put all objects in a hash table using their JSON representations as keys.

georg
  • 211,518
  • 52
  • 313
  • 390
  • be careful not to run that on too big collections of data. – naugtur Apr 04 '13 at 08:01
  • @naugtur: why? the performance is linear as far as I can tell. – georg Apr 04 '13 at 09:01
  • I guess I got worried by generating large strings from objects and then using them as keys in multiple sets. It might turn out memory-heavy, but I didn't test it - my bad. Anyway, it was not about time complexity at all. – naugtur Apr 05 '13 at 17:23
  • @thg435 If i have more than 30 items in my array, the `intersection` array throws one empty array. – Phoenix_uy Jun 19 '14 at 15:38
  • This was great, thank you so much! I was looking all around for a simple solution, appreciate it! – Sara Inés Calderón Sep 06 '18 at 23:22
0

Seems like you need to write some custom code to do object comparison in javascript (something like Object comparison in JavaScript) and then use an array intersecting algorithm (like one of the posters before mentioned) to find the common elements.

Community
  • 1
  • 1
Mahesh Guruswamy
  • 769
  • 5
  • 15