Filter Array Not in Another Array

Filter Array Not in Another Array

Need to filter one array based on another array. Is there a util function in knock out ? else i need to go with javascript

First :

var obj1 = [{
    "visible": "true",
    "id": 1
}, {
    "visible": "true",
    "id": 2
}, {
    "visible": "true",
    "id": 3
}, {
    "Name": "Test3",
    "id": 4
}];

Second :

var obj2 = [ 2,3]

Now i need to filter obj1 based on obj2 and return items from obj1 that are not in obj2 omittng 2,3 in the above data (Comparison on object 1 Id)

output:

[{
    "visible": "true",
    "id": 1
}, {
    "Name": "Test3",
    "id": 4
}];

3 Answers

You can simply run through obj1 using filter and use indexOf on obj2 to see if it exists. indexOf returns -1 if the value isn't in the array, and filter includes the item when the callback returns true.

var arr = obj1.filter(function(item){
  return obj2.indexOf(item.id) === -1;
});

With newer ES syntax and APIs, it becomes simpler:

const arr = obj1.filter(i => !obj2.includes(i.id))
0

Even if the answer provided by @Joseph are good, it can lead to performance issues if you have a very large array. The complexity is O(n^2), but it can be improved to O(n). Below I put the code I'd use to perform this task:

//create a map for storing object id
const map = new Map();
//add existing id from the array to the map
for (item of obj2) {
  map.set(item.id, true);
}

//create a new array that contains all items that aren't included in the //map
//the map lookUp is O(1) complexity
const arr = obj1.filter(item => !map[item.id]);

In this way we avoid nested iteration and have O(n) complexity

To create your output array, create a function that will iterate through obj1 and populate a new array based on whether the id of every obj in the iteration exists in obj2.

var obj1 = [{
    "visible": "true",
    "id": 1
}, {
    "visible": "true",
    "id": 2
}, {
    "visible": "true",
    "id": 3
}, {
    "Name": "Test3",
    "id": 4
}];

var obj2 = [2,3]

var select = function(arr) {
  var newArr = [];
  obj1.forEach(function(obj) {
    if obj2.indexOf(obj.id) !== -1 {
      newArr.push(obj)
    };
  };
  return newArr;
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross
Author

Alexander Ross

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.