46

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 3

92

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))
Sign up to request clarification or add additional context in comments.

Comments

3

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

1 Comment

I think checking existence in a set is faster than retrieving the 'true' value from a map medium.com/@dm_md/….
-1

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;
};

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.