Doug
Doug

Reputation: 1724

Can't filter object out of array

I'm trying to use the following to filter an object out of an array:

foo = [{foo: 'bar'}, {baz: 'bar'}];
bar = foo.filter(function(i) {
  return i !== {foo: 'bar'}
})

When I log bar afterwards, I get the full array.

The following code

foo.filter(function(i) {
  console.log(i === {foo: 'bar'});
  console.log(i);
  console.log({foo: 'bar'});
  return i !== {foo: 'bar'}
})

returns:

false
{ foo: 'bar' }
{ foo: 'bar' }
false
{ baz: 'bar' }
{ foo: 'bar' }
[ { foo: 'bar' }, { baz: 'bar' } ]

What am I missing here??

Upvotes: 1

Views: 416

Answers (4)

mwilson
mwilson

Reputation: 12980

Almost, i is the actual object. So you just need to compare i.foo to the string bar instead. Doing a comparison against an object like i === {} will never work. You would need to compare all of the properties in i and your object. There are plenty of deep compare helpers / examples out there if you were wanting that sort of thing.

Array.filter

/*
foo = [{foo: 'bar'}, {baz: 'bar'}];
bar = foo.filter(function(i) {
  return i !== {foo: 'bar'} // <-- You can't compare i to an object like this
})
*/

/**
* Array.filter will provide you with each object in your array.
* `i` is already the object in which you're trying to compare
* so you just need to access the property you want to compare (foo)
* and then compare if to the string 'bar'. i !== { prop: 'val' }
* will not give you accurate results
*/
foo = [{foo: 'bar'}, {baz: 'bar'}];
bar = foo.filter(function(i) {
  return i.foo !== 'bar'; // i is already the object. Access the property and then compare
});
console.log(bar);

If you think you need to run a deep compare, take a look at this: Object comparison in JavaScript

Upvotes: 2

Udochukwu Enwerem
Udochukwu Enwerem

Reputation: 2823

Using a shorter notation

let foo = [{foo: 'bar'}, {baz: 'bar'}];
let bar = foo.filter(i => i.foo !== 'bar');

console.log(bar);

Upvotes: 0

daydreamer
daydreamer

Reputation: 92169

You need to open up the object for the comparison. Something like this would work

foo = [{foo: 'bar'}, {baz: 'bar'}];
bar = foo.filter(function(i) {
   const [key, value] = Object.entries(i)[0];
   return key === 'foo' && value === 'bar'
})

Upvotes: -1

Jose Nuno
Jose Nuno

Reputation: 608

This would work:

const foo = [{foo: 'bar'}, {baz: 'bar'}];
const bar = foo.filter(function(i) {
  return i.foo !== 'bar'
});

console.log(bar);

You should compare the property 'foo' itself instead of comparing both objects

Upvotes: 3

Related Questions