294 votes

Comment obtenir l'index d'un objet par sa propriété en JavaScript ?

Par exemple, j'ai :

var Data = [
  { id_list: 1, name: 'Nick', token: '312312' },
  { id_list: 2, name: 'John', token: '123123' },
]

Alors, je veux trier/renverser cet objet par name par exemple. Et puis je veux obtenir quelque chose comme ça :

var Data = [
  { id_list: 2, name: 'John', token: '123123' },
  { id_list: 1, name: 'Nick', token: '312312' },
]

Et maintenant je veux connaître l'index de l'objet avec la propriété name='John' pour obtenir la valeur du jeton de propriété.

Comment puis-je résoudre le problème ?

0 votes

Pourquoi voulez-vous d'abord trier la liste avant de rechercher le bien ?

0 votes

Les objets JavaScript sont {Key:Value} je l'ai réparé pour toi.

0 votes

413voto

Puisqu'il a déjà été répondu à la question du tri. Je vais juste proposer une autre façon élégante d'obtenir l'indexOf d'une propriété dans votre tableau

Votre exemple est :

var Data = [
    {id_list:1, name:'Nick', token:'312312'},
    {id_list:2, name:'John', token:'123123'}
]

Vous pouvez le faire :

var index = Data.map(function(e) { return e.name; }).indexOf('Nick');

Array.prototype.map n'est pas disponible sur Internet Explorer 7 ou Internet Explorer 8. Compatibilité ES5

Et le voici avec ES6 et la syntaxe des flèches, qui est encore plus simple :

const index = Data.map(e => e.name).indexOf('Nick');

0 votes

Parfait ! Quelle est l'efficacité de cette méthode par rapport à celles expliquées ci-dessus ?

5 votes

Je dois itérer le tableau entier quoi qu'il arrive. La première méthode n'en a pas besoin.

1 votes

Simple, mais tenez compte des performances lorsque vous utilisez de grands ensembles de données.

292voto

silverlight513 Points 1416

Si l'utilisation de l'ES6 vous convient, les tableaux disposent désormais de la fonction findIndex fonction. Ce qui signifie que vous pouvez faire quelque chose comme ça :

const index = Data.findIndex(item => item.name === 'John');

8 votes

C'est de loin la solution la plus directe et la plus élégante, je ferais un petit pas pour que findIndex soit gourmand - dans mon cas c'était parfait - mais les utilisateurs doivent savoir que si vous avez des objets avec des valeurs dupliquées (c'est-à-dire deux objets avec name: John ), cela ne donnera que la première correspondance

0 votes

Génial ! Merci.

1 votes

@GrayedFox ne vouliez-vous pas dire NON gourmand ? Greedy signifie plus de résultats et findIndex ne renvoie que la première correspondance.

192voto

Chris Pickett Points 958

Comme les autres réponses le suggèrent, boucler dans le tableau est probablement la meilleure solution. Mais je la placerais dans sa propre fonction, et la rendrait un peu plus abstraite :

function findWithAttr(array, attr, value) {
    for(var i = 0; i < array.length; i += 1) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

var Data = [
    {id_list: 2, name: 'John', token: '123123'},
    {id_list: 1, name: 'Nick', token: '312312'}
];

Ainsi, vous pouvez non seulement trouver celui qui contient "John", mais aussi celui qui contient le jeton "312312" :

findWithAttr(Data, 'name', 'John'); // returns 0
findWithAttr(Data, 'token', '312312'); // returns 1
findWithAttr(Data, 'id_list', '10'); // returns -1

La fonction renvoie -1 si elle n'est pas trouvée, elle suit donc la même construction que la fonction Array.prototype.indexOf() .

1 votes

Ajout d'une réponse permettant de couvrir une recherche plus profonde qu'un niveau d'attribut. Merci pour cette réponse Chris - elle m'a beaucoup aidé :D

4 votes

Pour ceux qui auront des problèmes avec cette solution, rappelez-vous que le signe === égal ne vérifie pas seulement la valeur mais aussi le type de données. Ainsi, la comparaison de dates, de nombres et de valeurs vides peut renvoyer un résultat faux si la valeur réelle est une chaîne de caractères. Vous pouvez utiliser le signe égal == si le type de données n'a pas d'importance pour vous.

4 votes

NE FAITES PAS ÇA. Apprenez à utiliser les fonctions d'ordre supérieur, c'est l'ancienne façon de faire les choses.

36voto

Alain T. Points 1649

Si vous avez des problèmes avec Internet Explorer, vous pouvez utiliser la fonction map() qui est prise en charge à partir de 9.0 à l'avenir :

var index = Data.map(item => item.name).indexOf("Nick");

1 votes

La réponse ci-dessous fournit plus d'informations et a été publié en premier.

32voto

edank Points 548
var index = Data.findIndex(item => item.name == "John")

Ce qui est une version simplifiée de :

var index = Data.findIndex(function(item){ return item.name == "John"})

Desde mozilla.org :

La méthode findIndex() renvoie l'indice du premier élément du tableau qui satisfait à la fonction de test fournie. Sinon, -1 est renvoyé.

2 votes

Utilisez "===" pour la comparaison de chaînes de caractères, c'est la seule chose qui manque dans cette réponse.

0 votes

@BrunoTavares, quel scénario serait différent dans ce cas, selon vous ?

1 votes

@edank Si OP devait vérifier le token au lieu du champ name champ, il pourrait y avoir des problèmes, comme Data[0].token == 312312 évalue à true pero Data[0].token === 321321 évalue à false .

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