trouver l'index du tableau d'un objet avec une valeur de clé spécifique dans le trait de soulignement

91

En soulignant, je peux trouver avec succès un élément avec une valeur de clé spécifique

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
//data = { id: 2 }

mais comment puis-je trouver à quel index de tableau cet objet s'est produit?

mheavers
la source
duplication possible de Y a
Bergi
Merci - c'est utile - mais dans l'exemple listé, vous recherchez un seul nombre dans un tableau de nombres - je recherche une valeur clé dans un tableau d'objets. Cette fonction va-t-elle s'adapter à cela?
mheavers
2
Que ce soit un test numérique ou votre prédicat d'équité de propriété n'a pas d'importance, oui.
Bergi
Essayez findIndex:var dataIndex = _.findIndex(tv, { id: voteID })
Tom Söderlund
Veuillez envisager d'accepter la réponse qui donne une solution de soulignement , comme demandé dans la question.
Nigel

Réponses:

28

Je ne sais pas s'il existe une méthode de soulignement existante qui fait cela, mais vous pouvez obtenir le même résultat avec du javascript brut.

Array.prototype.getIndexBy = function (name, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][name] == value) {
            return i;
        }
    }
    return -1;
}

Ensuite, vous pouvez simplement faire:

var data = tv[tv.getIndexBy("id", 2)]

tewathia
la source
4
Pourquoi pas un return -1;par défaut?
Radu Chiriac
171

findIndex a été ajouté en 1.8:

index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })

Voir: http://underscorejs.org/#findIndex

Sinon, cela fonctionne également, si cela ne vous dérange pas de créer une autre liste temporaire:

index = _.indexOf(_.pluck(tv, 'id'), voteId);

Voir: http://underscorejs.org/#pluck

Ropez
la source
Je ne suis pas sûr du trait de soulignement, mais dans lodash, vous n'avez pas besoin d'une fonction anonyme, cela fonctionnera simplement index = _.findIndex(tv, {id: voteID}), fonctionne également si la tvcollection a des valeurs plus compliquées (plus qu'une simple idpropriété)
Scott Jungwirth
1
Juste un point utilisant pluck est tellement plus lent. I à cause de sa traversée supplémentaire. jsperf.com/compare-find-index
Farshid Saberi
38

Si vous souhaitez conserver le trait de soulignement pour que votre fonction de prédicat soit plus flexible, voici 2 idées.

Méthode 1

Étant donné que le prédicat pour _.findreçoit à la fois la valeur et l'index d'un élément, vous pouvez utiliser un effet secondaire pour récupérer l'index, comme ceci:

var idx;
_.find(tv, function(voteItem, voteIdx){ 
   if(voteItem.id == voteID){ idx = voteIdx; return true;}; 
});

Méthode 2

En regardant la source de soulignement, voici comment _.findest implémenté:

_.find = _.detect = function(obj, predicate, context) {
  var result;
  any(obj, function(value, index, list) {
    if (predicate.call(context, value, index, list)) {
      result = value;
      return true;
    }
  });
  return result;
};

Pour en faire une findIndexfonction, remplacez simplement la ligne result = value;par result = index;Ceci est la même idée que la première méthode. Je l'ai inclus pour souligner que le soulignement utilise également un effet secondaire pour implémenter _.find.

lastoneisbearfood
la source
37

Lo-Dash , qui étend Underscore, a la méthode findIndex , qui peut trouver l'index d'une instance donnée, ou par un prédicat donné, ou selon les propriétés d'un objet donné.

Dans votre cas, je ferais:

var index = _.findIndex(tv, { id: voteID });

Essaie.

éclat
la source
findIntex c'est une méthode de lo-dash, pas de underscore
Wallysson Nunes
4
@WallyssonNunes C'est exactement ce que j'ai écrit - "Lo-Dash, qui étend Underscore, a la méthode findIndex"
splintor
3
Cela fait maintenant partie de la bibliothèque de soulignements standard, à partir de la version 1.8.0: underscorejs.org/#1.8.0
Gage Trader
10

Si votre environnement cible prend en charge ES2015 (ou si vous avez une étape transpile, par exemple avec Babel), vous pouvez utiliser le natif Array.prototype.findIndex ().

Compte tenu de votre exemple

const array = [ {id:1}, {id:2} ]
const desiredId = 2;
const index = array.findIndex(obj => obj.id === desiredId);
craigmichaelmartin
la source
4

vous pouvez utiliser la indexOfméthode delodash

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
var index=_.indexOf(tv,data);
Amil Sajeev
la source
3

Gardez les choses simples:

// Find the index of the first element in array
// meeting specified condition.
//
var findIndex = function(arr, cond) {
  var i, x;
  for (i in arr) {
    x = arr[i];
    if (cond(x)) return parseInt(i);
  }
};

var idIsTwo = function(x) { return x.id == 2 }
var tv = [ {id: 1}, {id: 2} ]
var i = findIndex(tv, idIsTwo) // 1

Ou, pour les non-haters, la variante CoffeeScript:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)
joyrexus
la source
1
mieux seraitreturn parseInt(i) for i, x of array when cond(x)
meagar
1
comment c'est simple que les réponses précédentes ??
ncubica
2

C'est pour aider les lodashutilisateurs. vérifiez si votre clé est présente en faisant:

hideSelectedCompany(yourKey) {
 return _.findIndex(yourArray, n => n === yourKey) === -1;
}
Syed
la source
1

La solution la plus simple est d'utiliser le lodash:

  1. Installez lodash:

npm install - enregistrer lodash

  1. Utilisez la méthode findIndex:

const _ = require ('lodash');

findIndexByElementKeyValue = (elementKeyValue) => {
  return _.findIndex(array, arrayItem => arrayItem.keyelementKeyValue);
}
Jackkobec
la source
0

Si vous attendez plusieurs correspondances et que vous avez donc besoin d'un tableau à renvoyer, essayez:

_.where(Users, {age: 24})

Si la valeur de la propriété est unique et que vous avez besoin de l'index de la correspondance, essayez:

_.findWhere(Users, {_id: 10})
Ketan
la source
0
Array.prototype.getIndex = function (obj) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][Id] == obj.Id) {
            return i;
        }
    }
    return -1;
}

List.getIndex(obj);
Chinna Amara
la source
0

J'ai eu un cas similaire mais au contraire, c'est de trouver la clé utilisée en fonction de l'index d'un objet donné. Je pourrais trouver une solution dans le trait de soulignement en utilisant Object.valuespour renvoyer l'objet dans un tableau pour obtenir l'index produit.

var tv = {id1:1,id2:2};
var voteIndex = 1;
console.log(_.findKey(tv, function(item) {
  return _.indexOf(Object.values(tv), item) == voteIndex;
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

Chetabahana
la source