-4

I have followings object array

a = [{c:1, r:2}, {c:2, r:2}, {c:3, r:2}]
b = [{c:1, r:1}, {c:2, r:2}, {c:3, r:3}]

Now I want to remove common object this,

Like var result = removeCommon(a, b);
Output result = [{c:1, r:2}, {c:2, r:2}, {c:3, r:2}, {c:1, r:1}, {c:3, r:3}]

I need best way as array size is big

Urvish
  • 1,758
  • 4
  • 16
  • 23
  • possible duplicate of [Simplest code for array intersection in javascript](http://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript) – Naeem Shaikh Jan 08 '15 at 14:05
  • @NaeemShaikh : I need best way – Urvish Jan 08 '15 at 14:06
  • yes the accepted answer in that question is the best one! :) – Naeem Shaikh Jan 08 '15 at 14:07
  • as shown, none of those objects are actually common between arrays. you have to match only by value, and that's going to be really messy and long-winded. – dandavis Jan 08 '15 at 14:08
  • @NaeemShaikh : Solution given by assuming it is already sorted, but here it is not – Urvish Jan 08 '15 at 14:09
  • @Urvish you can sort and then intersect – Naeem Shaikh Jan 08 '15 at 14:10
  • @asimes: sure, but those two indentical-key+value objects are indeed not the same, and JS has no object-by-val comparision operator, only compare by ref, and they are not the same ref. so you need to serialize, or over-iterate to compare. it's one of the worst things about JS, but there's no easy answer... – dandavis Jan 08 '15 at 14:11
  • @NaeemShaikh : I dont want to sort, I just want to remove common – Urvish Jan 08 '15 at 14:11
  • @Qantas94Heavy : as in the code above I want the result ehich does not have {c:2, r:2} which is duplicate – Urvish Jan 08 '15 at 14:13
  • @Urvish: let me rephrase. Would you call `{c:2,r:2}` and `{c:2,r:2,z:2}` duplicates for the purpose of your code? – Qantas 94 Heavy Jan 08 '15 at 14:15
  • if the objects come from the same place and are indeed the same objects, any Array.uniuqe routine will work. if the objects are consistent in key-order, then you can compare the JSON.stringify() version of each to find duplicates via string compares (at least for now). – dandavis Jan 08 '15 at 14:15
  • This question seems to be asking for union (without duplicates), not intersection – Paul S. Jan 08 '15 at 14:16
  • Solution is _.uniq(a.concat(b), function(array){ return "c:" + array.c + "r:" + array.r; }) – Urvish Jan 08 '15 at 14:18

2 Answers2

2

I found the work around

_.uniq(a.concat(b), function(array){
    return "c:" + array.c + "r:" + array.r;
})

result : [{c:1, r:2}, {c:2, r:2}, {c:3, r:2}, {c:1, r:1}, {c:3, r:3}]
Urvish
  • 1,758
  • 4
  • 16
  • 23
  • yeah, but what about for {a:1,b:4} or {id:45432, total: 765} ? – dandavis Jan 08 '15 at 14:21
  • Looks like [Lo-Dash](https://lodash.com/docs#uniq) or [Underscore](http://underscorejs.org/#uniq), both have the same function signature (except Lo-Dash has an optional `thisArg`). – Qantas 94 Heavy Jan 08 '15 at 16:29
2

My solution (without external libraries):

var a = [{c:1, r:2}, {c:2, r:2}, {c:3, r:2}];
var b = [{c:1, r:1}, {c:2, r:2}, {c:3, r:3}];
var c = removeCommon(a, b);

console.log(c);

function removeCommon(a, b) {
  var result = {};

  a.concat(b).forEach(function (i) {
    result['c' + i.c + 'r' + i.r] = i;
  });

  return Object.keys(result).map(function (k) {
    return result[k];
  });
}

And a fiddle.

lante
  • 7,192
  • 4
  • 37
  • 57