6

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.

2
  • Do you want a new array, or to mutate the existing one? 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. Commented Aug 12, 2020 at 16:23

8 Answers 8

9

This 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);

Sign up to request clarification or add additional context in comments.

Comments

5

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

Comments

1

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

5 Comments

You're not deleting anything from the first array. Maybe the OP is fine with creating a new array, but the question does ask for mutation of the original.
@slappy just use array variable instead of filteredArray if you need dispose the main array from memory.
What if the OP has multiple references to the original array? You shouldn't assume that overwriting an array will be adequate when they ask for mutations.
Why i shoud not? It seems cost of traversing array using findIndex and splice is same as filter if it is not more.
It's not about performance; it's that they're not equivalent operations. If the OP has multiple references to array, and you overwrite one of them with the changes, the other references will not see the updates.
0

Use this oneliner from lodash.

const _ = require("lodash");
let filteredArray = _.remove(array, el=>[1,2].includes(el.id))

Comments

0

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

Comments

0

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

1 Comment

Those double quotes (, ) are not " and throw errors.
0

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.

Comments

0

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.

enter image description here

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.