I have an Array of Objects:
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }]
I have a second array containing the ID's that I want to filter out of the first Array:
const ids = [1, 2]
How do I create a new Array of Objects without the ID's found in ids
.
I have an Array of Objects:
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }]
I have a second array containing the ID's that I want to filter out of the first Array:
const ids = [1, 2]
How do I create a new Array of Objects without the ID's found in ids
.
- Do you want a new array, or to mutate the existing one? – Guerric P Commented Aug 12, 2020 at 16:18
- 1 Whenever there's a question asking how to perform deletions on an array, you end up with a bunch of answers showing how to make a new array and overwrite the original. Those are not equivalent operations. – user12407908 Commented Aug 12, 2020 at 16:23
8 Answers
Reset to default 9This is a fairly simple filter
operation
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
const ids = [1, 2];
var result = array.filter( x => !ids.includes(x.id));
console.log(result);
If you need to mutate the original array you can do like this:
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
const ids = [1, 2];
ids.forEach(idToDelete => {
const index = array.findIndex(({ id }) => id === idToDelete);
array.splice(index, 1);
});
console.log(array);
If you need a new array you can do like this:
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
const ids = [1, 2];
const result = array.filter(({ id }) => !ids.includes(id));
console.log(result);
You could also reassign a new array to the array
variable:
let array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
const ids = [1, 2];
array = array.filter(({ id }) => !ids.includes(id));
console.log(array);
Use Array.filter
:
let array = [
{id: 1, bar: "test" },
{id: 2, bar: "test2" },
{id: 3, bar: "test3" }
];
let ids = [1,2];
let filteredArray = array.filter(row=>!ids.includes(row.id));
console.log(filteredArray);
Use this oneliner from lodash.
const _ = require("lodash");
let filteredArray = _.remove(array, el=>[1,2].includes(el.id))
Use filter
and indexOf
.
const arr = [{ id: 1, bar: 'test' }, { id: 2, bar: 'test2' }, { id: 3, bar: 'test3' }];
const ids = [1, 2];
const result = arr.filter(element => ids.indexOf(element.id) === -1);
console.log(result);
We can filter an array in JavaScript using Array filter()
const myArray = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }]
const ids = [1,2]
const resultArray = myArray.filter(item => !ids.includes(item.id));
console.log(resultArray);
In term of performance the best solution will be the next one:
let array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
const ids = [1,2];
const idSet = new Set();
for (const id of ids) {
idSet.add(id);
}
array = array.filter(x => !set.has(x.id));
//const newArray if you need the initial array unmodified
In this case we perform two consequencial iteration instead of a nested one, so the time complexity will be O(n) instead of O(n^2);
##Edit
If you instead need the initial array to be mutated and not overwritten you can use this approach:
const ids = [1,2];
const array = [{id: 1, bar: "test" }, {id: 2, bar: "test2" }, {id: 3, bar: "test3" }];
for (const id of ids) {
const index = array.findIndex(x => x.id == id);
array.splice(index, 1);
}
In the second case the time complexity will be O(n*m), where n is array length and m is ids length.
I want to propose something wildly different.
In my case, I wanted to filter one list of unique IDs against another.
I was curious if regex could do it faster.
- Such a method really only works with one-dimensional arrays of simple objects.
- It's probably best if items a single regex 'word' (string of 0-9a-z_).
- A list of ids works perfect.
- array.filter works best on small datasets (1,000), usually slightly faster
- regex worked 66% faster on large datasets (10,000)
- regex speed advantage widens. 90% faster on 100,000.
- On comparing two arrays of 1m items, filter didn't do anything for me after more than 90 seconds. Regex returned a result in six seconds.
- In this case, the input is number[], and the output is string[], which works for my purposes, but you can use
map
to convert back to numbers if you need, .
var listlength = 10000;
function createArray() {
let arr = new Set();
for (let i = 0; i < listlength; i++) {
arr.add(Math.floor(Math.random() * listlength));
}
return arr;
}
function filter() {
let arr1 = Array.from(createArray());
let arr2 = Array.from(createArray());
let start = +new Date();
let arr3 = arr1.filter((n) => !arr2.includes(n));
console.log('filter', (+new Date() - start) + 'ms', arr1.length, arr2.length, arr3.length);
}
function regex() {
let arr1 = Array.from(createArray());
let arr2 = Array.from(createArray());
let start = +new Date();
let str1 = arr1.join(',') + ',';
str1 = str1.replace(new RegExp('\\b(' + arr2.join('|') + '),', 'g'), '');
let result = str1.split(',') // .map(e=>Number(e)); (to convert back to number[])
result.pop();
console.log('regex', (+new Date() - start) + 'ms', arr1.length, arr2.length, result.length);
}
for (let x = 0; x < 10; x++) {
console.log(`try ${x}`);
filter();
regex();
}
On my NodeJS app, sets of 100,000, regex more than 90% faster.