158 votes

Dans un tableau d'objets, le moyen le plus rapide de trouver l'index d'un objet dont les attributs correspondent à une recherche.

J'ai un peu navigué pour essayer de trouver un moyen efficace de le faire, mais je n'ai rien trouvé. J'ai un tableau d'objets qui ressemble à ceci :

array[i].id = some number;
array[i].name = some name;

Ce que je veux faire, c'est trouver les INDEX des objets où id est égal à, par exemple, l'un des 0, 1, 2, 3 ou 4. Je suppose que je pourrais simplement faire quelque chose comme :

var indexes = [];
for(i=0; i<array.length; i++) {
  (array[i].id === 0) ? { indexes[0] = i }
  (array[i].id === 1) ? { indexes[1] = i }
  (array[i].id === 2) ? { indexes[2] = i }
  (array[i].id === 3) ? { indexes[3] = i }
  (array[i].id === 4) ? { indexes[4] = i }
}

Bien que cela puisse fonctionner, il semble que cela soit assez coûteux et lent (sans parler de la laideur), surtout si array.length peut être grand. Avez-vous des idées pour améliorer un peu la situation ? J'ai pensé à utiliser array.indexOf d'une manière ou d'une autre mais je ne vois pas comment forcer la syntaxe. Voici

array.indexOf(this.id === 0);

par exemple, renvoie une valeur indéfinie, comme il se doit.

2voto

Tejs Points 23834

Il me semble que vous pourriez créer un simple itérateur avec un rappel pour les tests. Par exemple :

function findElements(array, predicate)
{
    var matchingIndices = [];

    for(var j = 0; j < array.length; j++)
    {
        if(predicate(array[j]))
           matchingIndices.push(j);
    }

    return matchingIndices;
}

Vous pourriez alors invoquer comme ceci :

var someArray = [
     { id: 1, text: "Hello" },
     { id: 2, text: "World" },
     { id: 3, text: "Sup" },
     { id: 4, text: "Dawg" }
  ];

var matchingIndices = findElements(someArray, function(item)
   {
        return item.id % 2 == 0;
   });

// Should have an array of [1, 3] as the indexes that matched

2voto

user2584621 Points 1

En adaptant la réponse de Tejs à mongoDB et Robomongo, j'ai modifié les éléments suivants

matchingIndices.push(j);

à

matchingIndices.push(NumberInt(j+1));

2voto

trungk18 Points 12923

Pour résumer toutes les excellentes réponses ci-dessus et ma réponse supplémentaire concernant la recherche de tous les index est issue de certains des commentaires.

  1. Pour retourner l'index de la première occurrence.

    const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }]; const idYourAreLookingFor = 2;

    //ES5 //Output: 1 array.map(function (x) { return x.id; }).indexOf(idYourAreLookingFor);

    //ES6 //Output: 1 array.findIndex(obj => obj.id === idYourAreLookingFor);

  2. Pour retourner le tableau d'index de toutes les occurrences, en utilisant reduce.

    const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }] const idYourAreLookingFor = 2;

    //ES5 //Output: [1, 4] array.reduce(function (acc, obj, i) { if (obj.id === idYourAreLookingFor) acc.push(i); return acc; }, []);

    //ES6 //Output: [1, 4] array.reduce((acc, obj, i) => (obj.id === idYourAreLookingFor) ? acc.concat(i) : acc, [])

1voto

patotoma Points 526

J'ai créé un petit utilitaire appelé super-réseau où vous pouvez accéder aux éléments d'un tableau par un identifiant unique avec une complexité O(1). Exemple :

const SuperArray = require('super-array');

const myArray = new SuperArray([
  {id: 'ab1', name: 'John'},
  {id: 'ab2', name: 'Peter'},
]);

console.log(myArray.get('ab1')); // {id: 'ab1', name: 'John'}
console.log(myArray.get('ab2')); // {id: 'ab2', name: 'Peter'}

1voto

SarahJ Points 11

Parfois, les anciennes méthodes sont les meilleures, comme l'a noté @PirateBay.

Avec ES 6/7, ".find" est aussi très rapide et s'arrête lorsqu'il correspond (contrairement à .map ou .filter).

items.find(e => e.id === find)?.id

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X