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?


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)]


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


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.


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.


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);

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);

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)

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

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);
}

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})

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);

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>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.