raben
raben

Reputation: 3100

Compare two arrays of objects and remove items in the second one that have the same property value

All I need to do is compare two arrays of objects and remove items in the second one that have the same property value. For example:

var a = [{'name':'bob', 'age':22}, {'name':'alice', 'age':12}, {'name':'mike', 'age':13}];
var b = [{'name':'bob', 'age':62}, {'name':'kevin', 'age':32}, {'name':'alice', 'age':32}];

function remove_duplicates(a, b) {
    for (var i = 0, len = a.length; i < len; i++) {
        for (var j = 0, len = b.length; j < len; j++) {
            if (a[i].name == b[j].name) {
                b.splice(j, 1);
            }
        }
    }

    console.log(a);
    console.log(b);

}

console.log(a);
console.log(b);

remove_duplicates(a,b);

I cannot understand why this does not work and instead gives:

Uncaught TypeError: Cannot read property 'name' of undefined

What I expected was the following content in b:

[{'name':'kevin', 'age':32}];

Upvotes: 15

Views: 69097

Answers (9)

saikeerthi kotha
saikeerthi kotha

Reputation: 11

var a = [{ 'name': 'bob', 'age': 22 }, { 'name': 'alice', 'age': 12 }, { 'name': 'mike', 'age': 13 }, { 'name': 'keerthi', 'age': 62 }];
var b = [{ 'name': 'bob', 'age': 62 }, { 'name': 'kevin', 'age': 32 }, { 'name': 'alice', 'age': 32 }, { 'name': 'keerthi', 'age': 62 }];

a.map((firstObj) => {
      b.map((compareObj, i) => {
        if (firstObj.name === compareObj.name) {
          b.splice(i, 1);
    }
  })
})

console.log(b)

Upvotes: 1

rahulxyz
rahulxyz

Reputation: 445

let A = [
  {name: 'a', age: 20},
  {name: 'b', age: 30},
  {name: 'c', age: 10},
]

let B = [
  {name: 'a', age: 20},
  {name: 'b', age: 40},
  {name: 'd', age: 10},
  {name: 'e', age: 20},
  {name: 'f', age: 10},
]

const compareName = (obj1, obj2)=>{
  return (obj1.name === obj2.name);
}

const compareAll = (obj1, obj2)=>{
  return (obj1.name === obj2.name && obj1.age=== obj2.age);
}

let output = B.filter(b=>{
  let indexFound = A.findIndex(a => compareName(a, b));
  return indexFound == -1;
})

Depending on which Objects you want to remove use:

  1. compareName : Remove objects which have common name
  2. compareAll : Remove objects which have both name & age common

Also to find common Objects list just add use return index != -1

PS: Refer my Github for Array Data Manipulation examples in Javascript

Upvotes: 1

Geole
Geole

Reputation: 376

Instead of using two loops you might also use the findIndex function:

for (var i = 0, len = a.length; i < len; i++) {
    var ItemIndex = b.findIndex(b => b.name === a[i].name);

    a.splice(ItemIndex, 1)
}

Or if you want to go completely without using a loop you might use the forEach function

a.forEach(function(item, index, array) {
    var ItemIndex = b.findIndex(b => b.name === item.name);

    a.splice(ItemIndex, 1)
}

Upvotes: 6

Narendran
Narendran

Reputation: 735

compare and remove in array of object.Typically array of object data type may be typeOf is object.So that we need to convert into JSON stringify and then check condition..

for(var i=0; i < a.length; i++) {
                    for(var j=0; j < b.length; j++) {
                        if(JSON.stringify(a[i])  == JSON.stringify(b[j])) {
                            a.splice(i, 1);
                        }
                    }
                }

Upvotes: 1

Snippet
Snippet

Reputation: 1560

FIDDLE

 for (var i = 0, len = a.length; i < len; i++) { 
        for (var j = 0, len2 = b.length; j < len2; j++) { 
            if (a[i].name === b[j].name) {
                b.splice(j, 1);
                len2=b.length;
            }
        }
    }

Upvotes: 23

AlwaysALearner
AlwaysALearner

Reputation: 43947

You just need to break the inner loop when a match is found:

if (a[i].name == b[j].name) {
    b.splice(j, 1);
    break;
}

Upvotes: 3

Dhaval Marthak
Dhaval Marthak

Reputation: 17366

Try this:

You are starting loop from the 0.

for (var i = 0, len = a.length; i < len; i++) {
        for (var j = 0, len = b.length; j < len-1; j++) {
            if (a[i].name == b[j].name) {
                b.splice(j, 1);
            }
        }
    }

Fiddle Demo

Upvotes: 1

Phong Vo
Phong Vo

Reputation: 1078

The root cause is that you directly splice items from array b while you are in the for loop and pre condition is a and b have same number of items.

Upvotes: 0

Sirko
Sirko

Reputation: 74036

Your problem is, that splice() will change the length of the array, so that your precalculated len value will be too large and the inside the loop you try to access undefined elements.

A possible solution would be to use the filter() method:

function remove_duplicates(a, b) {

  b = b.filter( function( item ) {
      for( var i=0, len=a.length; i<len; i++ ){
          if( a[i].name == item.name ) {
              return false;
          }
      }
      return true;
  });

  console.log(a);
  console.log(b);
}

Example Fiddle

Upvotes: 4

Related Questions