1

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??

Doug
  • 1,517
  • 3
  • 18
  • 40

4 Answers4

3

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

Jose Nuno
  • 598
  • 3
  • 13
2

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

mwilson
  • 12,295
  • 7
  • 55
  • 95
0

Using a shorter notation

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

console.log(bar);
Udo E.
  • 2,665
  • 2
  • 21
  • 33
-1

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'
})
daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • (Didn't down vote you). I like your catch on comparing the property AND value. but I think op is strictly after the object where the property foo is equal to bar – mwilson Aug 21 '19 at 23:22