How to find the index of an object in a javascript list

Asked

Viewed 292 times

3

I am trying to get the index of an object in the following list:

let list = [
{nome: joão, idade: 15},
{nome: pedro, idade: 17},
{nome: felipe, idade: 12},
]

But when I try to use command list.indexOf({nome: felipe, idade: 12}) it returns -1

How can I get the index of an object in a list the right way?

4 answers

6


The method Array.findIndex allows to find the index of the element that satisfies a certain condition.

let list = [
    {nome: "joão", idade: 15},
    {nome: "pedro", idade: 17},
    {nome: "felipe", idade: 12},
]
    
let index = list.findIndex(i => i.nome === "felipe" && i.idade === 12);

console.log(index);

  • Finally a reply that worked! Thank you very much.

4

Objects with the same content are not equal, that is to say comparing objects with equality is always different unless they are a reference to each other. This happens because each object is a different instance.

To clarify:

{foo: '123'} == {foo: '123'} // false
{foo: '123'} === {foo: '123'} // false
const foo = {foo: '123'}; 
const foo2 = foo;
foo === foo2 // true 
JSON.stringify({foo: '123'}) === JSON.stringify({foo: '123'}) // true

That is, in your case you will have to compare by strings, or search for properties values of the object like the G. Bittencourt referred.

In principle you could compare strings, as in the last example above... but this can give problems if the order of the properties is different. I suggest you use a function that compares properties on a given object, but you should keep in mind that if there are 2 objects with the same properties it will return the first one you find.

Using the .findIndex and passing the check to your callback:

let list = [
  {nome: 'joão', idade: 15},
  {nome: 'pedro', idade: 17},
  {nome: 'felipe', idade: 12}
];

const getIndexOfObject = (arr, ...props) => arr.findIndex(
    el => props.every(([key, value]) => el[key] === value)
); 

const index = getIndexOfObject(list, ['nome', 'pedro'], ['idade', 17]);
console.log(index); // 1

  • Thus, comparing objects as strings, if the parameter passed was in the order { idade: 17, nome: 'pedro' }, the function would return -1, nay?

  • @G.Bittencourt true, I was correcting that. Corrected now.

  • 1

    Great your solution.

3

If you want to compare for an object directly, you can do something like this:

const l = [
  { nome: 'João', idade: 15 },
  { nome: 'Pedro', idade: 17 },
  { nome: 'Felipe', idade: 12 }
];

function findIndex(list, obj) {
  return list.findIndex((current) =>
    Object.keys(current).every((key) => obj[key] === current[key])
  );
}

console.log(findIndex(l, { nome: 'Felipe', idade: 12 })); // 2

Remembering that it will not work with nested objects, since the comparator === does not compare objects by their values, but rather by reference. But I don’t think this is your case.

2

An alternative is to use lib Lodash. In that lib there is the method _.isEqual() which makes the comparison between objects independent of the order in which their properties were declared.

To get the index in the array use the native method Array.prototype.findIndex() which returns the index in the array of the first element that satisfies the provided test function.

let l = [
  {nome: "joão", idade: 15},
  {nome: "pedro", idade: 17},
  {nome: "felipe", idade: 12}
]

function índiceDe(objeto, lista) {
  return lista.findIndex(e => _.isEqual(e, objeto));
}

console.log(índiceDe({nome: "felipe", idade: 12},l))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.