27

I'm new in JavaScript programming and I have two object arrays that have the following structure:

myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

I need to get two separate arrays containing the values of key foo, the first containing the ones that are in the first array but not in the second, based on the value of key foo, and the second that are in mySecondObjArray but not in myFirstObjArray.

Is there a way to do this without

for(i=0;i<myFirstObjArray.length;i++)
   for(j=0;j<mySecondObjArray .length;j++)
      {...build first array here}

for(i=0;i<mySecondObjArray .length;i++)
   for(j=0;j<myFirstObjArray.length;j++)
      {...build second array here}

? Perhaps my question is a duplicate one that I didn't find, so please be gentle.

Expected output:

firstArray = [{foo: 1}, {foo: 3}];
secondArray = [{foo: 2}, {foo: 5}];
5
  • add your expected output here Commented Jun 13, 2018 at 12:05
  • @GeorgeBailey updated my question Commented Jun 13, 2018 at 12:07
  • @Dana: I added answer in ES5 to support all browsers including IE Commented Jun 13, 2018 at 12:22
  • Possible duplicate of How to get the difference between two arrays in Javascript? Commented Jun 13, 2018 at 13:40
  • In most languages this is called something along the lines of "array diff". Commented Jun 13, 2018 at 13:40

5 Answers 5

25

You can simply filter one array's elements by setting the condition based on other array's elements like.

var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}],
    
    firstArray  = myFirstObjArray.filter(o=> !mySecondObjArray.some(i=> i.foo === o.foo));
    
    secondArray  = mySecondObjArray.filter(o=> !myFirstObjArray.some(i=> i.foo === o.foo));
    
    console.log(firstArray.map(o=> {return {'foo' :  o.foo}}))
    console.log(secondArray.map(o=> {return {'foo' :  o.foo}}))

Ps:

The some() method tests whether at least one element in the array passes the test implemented by the provided function. And I've added a function which just checks if foo property exists in the other array with the same value to be able to filter from the first array.

At the end you can use .map to filter out the desired key value pairs

Hope that makes sense

Read more about .some and filter

Sign up to request clarification or add additional context in comments.

3 Comments

First array should contain only foo properties, so OP propably needs to read about map too
Does not provide the expected output
this helped me, thank you allRoles?.filter((r) => !userRoles?.some((ur) => ur.id === r.id)).map((role)
10

Here is a small solution with just filter and a map with the foo attribute.

const myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
const mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

const exclude = (arr1, arr2) => arr1.filter(o1 => arr2.map(o2 => o2.foo).indexOf(o1.foo) === -1);

console.log(exclude(myFirstObjArray, mySecondObjArray));
console.log(exclude(mySecondObjArray, myFirstObjArray));

1 Comment

Prefer includes to indefOf
2

ES5 without using fat arrow,

var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}],
    
    firstArray  = myFirstObjArray.filter(function(o) { return !mySecondObjArray.some(function(i) { return i.foo === o.foo})});
     
    secondArray  = mySecondObjArray.filter(function(o) { return !myFirstObjArray.some(function(i) { return i.foo === o.foo})});
    
    console.log(firstArray)
    console.log(secondArray)

Comments

1

You could filter by look up.

const unique = a => o => !a.some(({ foo }) => o.foo === foo);

var first = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    second = [{foo: 2}, {foo: 4}, {foo: 5}],
    uniqueFirst = first.filter(unique(second)),
    uniqueSecond = second.filter(unique(first));
    
console.log(uniqueFirst);
console.log(uniqueSecond);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

You can create a reusable function to prevent code duplication. Just switch over to the function parameter. Also note that the inner loop is simple for loop so that we can use break and avoid unnecessary checks.

var firstArray = [];
var secondArray = [];
var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
var mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

function difference(myFirstObjArray, mySecondObjArray){
  var firstArray = [];
  myFirstObjArray.forEach((obj)=>{
   var match = false;
   for(var i=0; i<mySecondObjArray.length; i++){
     var secondObj = mySecondObjArray[i];
     if(obj.foo === secondObj.foo){
       match = true;
       break;
     }
   }
   if(!match){
     firstArray.push({'foo': obj.foo});
   }
  });
  return firstArray;
}


console.log(difference(myFirstObjArray, mySecondObjArray));

console.log(difference(mySecondObjArray, myFirstObjArray));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.