0

I'm trying to find an exact match in an array. I have my array array with a single object, and an exact match stored in example. When I iterate over the array array, it goes right past it. I discovered this when working with a much larger array, but broke it down to a single 1/1 relationship for a sort of 'proof of concept'. I feel like the answer is simple and staring right at me, but I don't see it. Save me.

'use strict';

var array = [ { foo: 'hello', bar: 'foo' } ];

var example = { foo: 'hello', bar: 'foo' };

for (var i = 0; i < array.length; i++) {
  if ( array[i] === example ) {
    console.log(array[i]);
  }
}
Dustin Stiles
  • 1,414
  • 9
  • 12

2 Answers2

0

You can compare objects like so:

JSON.stringify(obj1) === JSON.stringify(obj2) 

In your case you would be looking for:

var array = [ { foo: 'hello', bar: 'foo' } ];
var example = { foo: 'hello', bar: 'foo' };

for (var i = 0; i < array.length; i++) {
    if ( JSON.stringify(array[i]) === JSON.stringify(example) ) {
        console.log(array[i]);
    }
}

You can't compare objects the way you did because you are then comparing instances.

I should note that this way of comparing objects is very limited and only works if the properties share the same order, and do not include functions, etc. You could sort the property order, or compare deeper equality with any of the popular solutions that may be found here: Object comparison in JavaScript

Community
  • 1
  • 1
Max
  • 2,710
  • 1
  • 23
  • 34
  • 1
    You should explain why this works. – styvane Oct 18 '15 at 05:41
  • Wow, that totally works. Why does it not recognize it when it's still an object though? I get that converting them to JSON makes sure they are formatted the same way, but is an object in an array any different than an unwrapped object? – Dustin Stiles Oct 18 '15 at 05:42
  • 2
    What if one of the objects is defined as `{ bar: 'foo', foo: 'hello' }`? – Felix Kling Oct 18 '15 at 05:43
  • user3100115 *thumbs up* – Dustin Stiles Oct 18 '15 at 05:43
  • You called it out of the array, so that doesn't change anything.... I'll exaplain why you can't compare them in another way.. 1sec. – Max Oct 18 '15 at 05:43
  • @Dustin: *"Why does it not recognize it when it's still an object though?"* Two different **instances** are never equal. *"I get that converting them to JSON makes sure they are formatted the same way"* Only coincidentally. That's **not** a reliable approach. *"is an object in an array any different than an unwrapped object"* No. – Felix Kling Oct 18 '15 at 05:44
  • *"You can't compare object literals"* That has nothing to do with *literals*. The way *how* the objects were created doesn't matter. – Felix Kling Oct 18 '15 at 05:45
  • @FelixKling If the object property order is not the same, you could sort it. More tedious work. – Max Oct 18 '15 at 05:48
  • The `stringify` approach is fundamentally flawed. It will fail if a property value is a function or a regexp. It will fail if the properties are enumerated in different orders. It will fail if there's a circular reference in the object. It is slow. There are much better well-established ways to determine deep object equality. –  Oct 18 '15 at 05:50
  • Mind if I update the answer with that before you downvote it? – Max Oct 18 '15 at 05:51
  • Yes if the properties are not in the same order it won't match. @FelixKling thank you for the answers, the fact they are two different instances makes sense. Thanks again everyone for the quick and informative responses! – Dustin Stiles Oct 18 '15 at 05:51
0

Consider using _.isEqual from popular (almost standard substitute for native) utility libraries such as underscore.js or lodash.js

for (var i = 0; i < array.length; i++) {
  if ( _.isEqual(array[i], example) ) {
    console.log(array[i]);
  }
}
Ling Zhong
  • 1,744
  • 14
  • 24
  • You don't need to implement an entire library to achieve deep object comparisons. – Max Oct 18 '15 at 05:56
  • I was using underscore but I only needed it for comparisons. I decided to work on my own implementation of just that feature, instead of pulling in the entire library. I didn't make it very far, but I have hope :) – Dustin Stiles Oct 18 '15 at 06:01