Muzammil Versiani
Muzammil Versiani

Reputation: 191

Angular 6 compare two JSON Arrays

I am fetching notifications using API. Now here is the scenario:

1- I called the API, got 2 records and stored them in local variable (notifications) to show in view.

[{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}]

2- I am calling the same API to check for new notification after every 5 seconds. This time I need to compare the API response with the local variable, so if no new notification (different id) is in the record, don't push in local variable, other push.

I have tried something like this:

var val = JSON.parse(data);
if( val.length > 0 ) {
    for( var i = 0; i < val.length; i++ ) {
        this.notifications.forEach(element => {
            if( element.id != val[i].id ) {
                this.notifications.push(val[i]);
            }
        });

    }
}

But its adding duplicate records. Any help would be appreciated.

Thanks

Upvotes: 3

Views: 9413

Answers (2)

Ankit Sharma
Ankit Sharma

Reputation: 1704

A more robust way to handle this could be by using map in JS.

Rather than iterating the notifications (size = m) for every object in the data (size = n) would result in more time complexity of O(m x n).

Hence it could be done in O(n) as below:-

var notifications = new Map();

// assuming you get this at the beginning
var data1 = `[{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}]`;

checkAndAddNotification(data1);

// assuming you get this at the second time
var data2 = `[{"id": 1, "notification": "bla"}, {"id": 4, "notification": "bla bla bla"}]`

checkAndAddNotification(data2);

function checkAndAddNotification(data){
  var val = JSON.parse(data);
  
  if (val){
    val.forEach((obj)=>{
     var existNotification = notifications.get(obj.id);
     
     if(!existNotification){
       notifications.set(obj.id, obj);
     }
   });
  }
}

console.log(notifications);

notifications.forEach((notification) => console.log(notification));

Please open the browser console as well while running the code.

Even if you plan to iterate over the map, the order would be preserved in the order the objects were inserted. Please look here for more.

Upvotes: 1

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

You need to use Array.find() to find the duplicate object in the val array.

var notifications = [{"id": 1, "notification": "bla"}, {"id": 2, "notification": "bla bla"}];

var data = `[{"id": 1, "notification": "bla"}, {"id": 4, "notification": "bla bla bla"}]`

var val = JSON.parse(data);
if( val.length > 0 ) {
   val.forEach((obj)=>{
     var existNotification = notifications.find(({id}) => obj.id === id);
     if(!existNotification){
       notifications.push(obj);
     }
   });
}
console.log(notifications);

Currently, you are getting duplicated element because the id value is compared against all the existing id values in notifications array. So, if one of the id do not match with another, it is pushed immediately into the notifications array. So, the better way and simple way is to use a find operation on the array to check the existing object.

Upvotes: 5

Related Questions