web-dev-qa-db-fra.com

Comment obtenir l'index d'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' },
]

Ensuite, je veux trier/inverser cet objet par name, par exemple. Je reçois 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é.

168
rsboarder

Comme le suggèrent les autres réponses, il est probablement préférable de parcourir le tableau en boucle. Mais je le mettrais dans sa propre fonction et le rendrais un peu plus abstrait:

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'}
];

Avec cela, vous pouvez non seulement trouver lequel contient 'John' mais vous pouvez trouver qui contient le jeton '312312':

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

EDIT: La fonction mise à jour renvoie -1 si elle est introuvable. Elle suit donc la même construction que Array.prototype.indexOf ()

136
Chris Pickett

Depuis la partie de tri est déjà répondu. Je vais juste proposer une autre manière é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'}
]

Tu peux faire:

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

Array.prototype.map n'est pas disponible sur IE7 ou IE8. Compatibilité ES5

Et voici la syntaxe ES6 et arrow, qui est encore plus simple:

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

Si vous êtes d'accord avec ES6. Les tableaux ont maintenant la fonction findIndex . Ce qui signifie que vous pouvez faire quelque chose comme ça:

const index = Data.findIndex(item => item.name === 'John');
131
silverlight513
var index = Data.findIndex(item => item.name == "John")

Qui est une version simplifiée de:

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

De mozilla.org:

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

13
edank

La seule façon connue pour moi est de parcourir en boucle tous les tableaux:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name==="John"){index=i;break;}

ou insensible à la casse:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name.toLowerCase()==="john"){index=i;break;}

On result variable index contient l'index de l'objet ou -1 s'il n'est pas trouvé.

4
Andrew D.

Si vous rencontrez des problèmes avec IE, vous pouvez utiliser la fonction map () qui est prise en charge à partir de la version 9.0:

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

une manière prototypique

(function(){
  if (!Array.prototype.indexOfPropertyValue){
    Array.prototype.indexOfPropertyValue = function(prop,value){
      for (var index = 0; index < this.length; index++){
        if (this[index][prop]){
          if (this[index][prop] == value){
            return index;
          }
        }
      }
      return -1;
    }
  }
 })();
 // usage:
 var Data = [
 {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}];
 Data.indexOfPropertyValue('name','John'); // returns 1 (index of array);
 Data.indexOfPropertyValue('name','Invalid name') // returns -1 (no result);
 var indexOfArray = Data.indexOfPropertyValue('name','John');
 Data[indexOfArray] // returns desired object.
2
Patrik Wallin

Pourquoi n'utilisez-vous pas un petit problème?

Créez un nouveau tableau avec des noms sous forme d'index. Après cela, toutes les recherches utiliseront des index. Donc, une seule boucle. Après cela, vous n'avez pas besoin de parcourir tous les éléments!

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
    ]
var searchArr = []
Data.forEach(function(one){
  searchArr[one.name]=one;
})
console.log(searchArr['Nick'])

http://jsbin.com/xibala/1/edit

exemple en direct.

2
user4466709
var fields = {
teste:
{
    Acess:
    {
        Edit: true,
      View: false

      }
 },
teste1:
{
    Acess:
    {
        Edit: false,
      View: false

      }
  }
};

console.log(find(fields,'teste'));
function find(fields,field){
    for(key in fields){
        if(key == field){
        return true;
    }
}
return false;
}

Si vous avez un objet avec plusieurs objets à l'intérieur, si vous voulez savoir si certains objets sont inclus dans l'objet maître, mettez simplement find (MasterObject, 'Object to Search'), cette fonction retournera la réponse si elle existe ou non (TRUE ou FALSE ), J'espère que l'aide avec ceci, peut voir l'exemple sur JSFiddle .

1

Et ça ? :

Data.indexOf(_.find(Data, function(element) {
  return element.name === 'John';
}));

En supposant que vous utilisez lodash ou underscorejs.

1
Ellone
let indexOf = -1;
let theProperty = "value"
let searchFor = "something";

theArray.every(function (element, index) {

    if (element[theProperty] === searchFor) {
        indexOf = index;
        return false;
    }
    return true;
});
1
Itay Merchav

Vous pouvez utiliser Array.sort en utilisant une fonction personnalisée en tant que paramètre pour définir votre mécanisme de tri.

Dans votre exemple, cela donnerait: 

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

Data.sort(function(a, b){
    return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
});

alert("First name is : " + Data[0].name); // alerts 'John'
alert("Second name is : " + Data[1].name); // alerts 'Nick'

La fonction de tri doit renvoyer soit -1 si a devrait venir avant b, 1 si a devrait venir après b et 0 si les deux sont égaux. C'est à vous de définir la bonne logique dans votre fonction de tri pour trier le tableau.

Edit: Vous avez manqué la dernière partie de votre question pour laquelle vous souhaitez connaître l'index. Vous devrez parcourir le tableau pour trouver cela, comme d'autres l'ont déjà dit.

1
StevenGilligan

Il suffit de parcourir votre tableau et de trouver la position:

var i = 0;
for(var item in Data) {
    if(Data[item].name == 'John')
        break;
    i++;
}
alert(i);
1
Sascha Galley

Réponse étendue de Chris Pickett parce que dans mon cas, je devais rechercher plus d'un niveau d'attribut:

function findWithAttr(array, attr, value) {
  if (attr.indexOf('.') >= 0) {
    var split = attr.split('.');
    var attr1 = split[0];
    var attr2 = split[1];
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr1][attr2] === value) {
        return i;
      }
    }
  } else {
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr] === value) {
        return i;
      }
    }
  };
};

Vous pouvez passer 'attr1.attr2' dans la fonction

1
Ed Shee

Cela pourrait être utile

function showProps(obj, objName) {  
  var result = "";  
  for (var i in obj)  
    result += objName + "." + i + " = " + obj[i] + "\n";  
  return result;  
}

Copié cela depuis https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects

1
Ashish

Au lieu de la réponse de l'allemand Attanasio Ruiz, vous pouvez éliminer la deuxième boucle en utilisant Array.reduce () au lieu de Array.map ();

var Data = [
    { name: 'hypno7oad' }
]
var indexOfTarget = Data.reduce(function (indexOfTarget, element, currentIndex) {
    return (element.name === 'hypno7oad') ? currentIndex : indexOfTarget;
}, -1);
0
hypno7oad
collection.findIndex(item => item.value === 'smth') !== -1
0
Eugene Lyzo