13

UPDATE: Although this question is marked as duplicated with this. But @ssube's way is neat and much smarter.

UPDATE2: Seems there is new way to do it in the comment by @Grungondola.

I am using Typescript.

This works well.

var array1 = [];
array1.push(5);
array1.push(6);
console.log("a", array2.indexOf(6));

But this does not work well. Because array2.indexOf returns -1 which means it does not find it.

var array2 = [];
array2.push({aa:5,bb:5});
array2.push({aa:6,bb:6});
console.log(array2.indexOf({aa:6,bb:6}));

Looks like indexOf does not support Object. Does TypeScript have its own ways to deal with this kind of problem? Thanks.

5
  • This really has nothing to do with TypeScript. In JavaScript two objects are never equal. You'll have to write a custom search. Commented Feb 4, 2016 at 17:05
  • indexOf() is a method for objects of type String, not Array Commented Feb 4, 2016 at 17:05
  • Sorry, I'm mistaken. There are an indexOf() for arrays : developer.mozilla.org/es/docs/Web/JavaScript/Referencia/… . Thousands of sorrys :( Commented Feb 4, 2016 at 17:06
  • 2
    As of es2015, there is a function on arrays called findIndex that accepts a predicate in the same way as find and would allow you to do a deep search for the object that you want. I would provide this as an answer, but answering is not possible any more. The problem with this is that it lacks support in IE for some reason, but there is a polyfill that you can add for that: findIndex Reference Commented Oct 31, 2018 at 12:13
  • If the purpose is just to know if an element exists refer to array.some Commented Dec 7, 2018 at 16:20

1 Answer 1

29

No. The problem is not with Object, but that you are creating two different objects.

The object literal syntax ({foo: 'bar'}) declares an object inline. When the script is executed, the object is created. Using that syntax multiple times creates multiple objects.

You can easily test that with {foo: 3} === {foo: 3}. This will evaluate to false, but they are not the same object (reference).

The indexOf method checks if the object, string, number, etc, is present in the array. You're passing a new object, which is not in the array.

If you have a reference to the object, you can use that and indexOf will work:

var foo = {aa:5,bb:5}, bar = {aa:6,bb:6};
var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(array2.indexOf(foo));

Because you're referring to the same instance, this will print the index.

You can also use filter or find with a predicate to perform a deep search:

function deepIndexOf(arr, obj) {
  return arr.findIndex(function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}

var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(deepIndexOf(array2, foo));

This won't recurse into nested objects, but will accomplish the comparison you're looking for (equivalence on two objects and their immediate fields).

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

1 Comment

Premature optimization et cetera, but this could be optimized. At least, getting the keys and values from arr before the loop... And where are those nice arrow functions? They could maximize the simplicity to its half ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.