Suchen Sie den Array-Index eines Objekts mit einem bestimmten Schlüsselwert im Unterstrich

89

Im Unterstrich kann ich erfolgreich einen Artikel mit einem bestimmten Schlüsselwert finden

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

Aber wie finde ich, an welchem ​​Array-Index dieses Objekt aufgetreten ist?

mheavers
quelle
Danke - das ist nützlich - aber in dem aufgelisteten Beispiel suchen Sie nach einer einzelnen Zahl in einem Array von Zahlen - ich suche nach einem Schlüsselwert in einem Array von Objekten. Wird diese Funktion das berücksichtigen?
Mheavers
2
Ob es sich um einen numerischen Test oder um Ihr Eigenschaftsgleichheitsprädikat handelt, spielt keine Rolle, ja.
Bergi
Versuchen Sie findIndex:var dataIndex = _.findIndex(tv, { id: voteID })
Tom Söderlund
Bitte akzeptieren Sie die Antwort, die eine Unterstreichungslösung ergibt , wie in der Frage gefordert.
Nigel B. Peck

Antworten:

28

Ich weiß nicht, ob es eine Unterstrichmethode gibt, die dies tut, aber Sie können das gleiche Ergebnis mit einfachem Javascript erzielen.

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

Dann können Sie einfach tun:

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

Tewathia
quelle
4
Warum nicht return -1;standardmäßig ein?
Radu Chiriac
170

findIndex wurde in 1.8 hinzugefügt:

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

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

Alternativ funktioniert dies auch, wenn es Ihnen nichts ausmacht, eine andere temporäre Liste zu erstellen:

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

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

Ropez
quelle
Ich bin nicht sicher über Unterstrich, aber in lodash brauchen Sie keine anonyme Funktion, wird einfach index = _.findIndex(tv, {id: voteID})funktionieren, funktioniert auch, wenn die tvSammlung kompliziertere Werte hat (mehr als nur eine idEigenschaft)
Scott Jungwirth
1
Nur ein Punkt mit Zupfen ist so viel langsamer. Ich wegen seiner zusätzlichen Durchquerung. jsperf.com/compare-find-index
Farshid Saberi
38

Wenn Sie beim Unterstrich bleiben möchten, damit Ihre Prädikatfunktion flexibler ist, finden Sie hier zwei Ideen.

Methode 1

Da das Prädikat für _.findsowohl den Wert als auch den Index eines Elements empfängt, können Sie den Index mithilfe des Nebeneffekts wie folgt abrufen:

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

Methode 2

Mit Blick auf die Unterstrichquelle wird _.findfolgendermaßen implementiert:

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

Um dies zu einer findIndexFunktion zu machen , ersetzen Sie einfach die Zeile result = value;durch result = index;Dies ist die gleiche Idee wie bei der ersten Methode. Ich habe es aufgenommen, um darauf hinzuweisen, dass der Unterstrich auch Nebeneffekte zur Implementierung verwendet _.find.

lastoneisbearfood
quelle
37

Lo-Dash , das Underscore erweitert, verfügt über findIndex Methode, mit der der Index einer bestimmten Instanz oder anhand eines bestimmten Prädikats oder gemäß den Eigenschaften eines bestimmten Objekts ermittelt werden kann.

In Ihrem Fall würde ich tun:

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

Versuche es.

Schiene
quelle
findIntex es ist eine Methode von Lo-Dash, nicht von Unterstrich
Wallysson Nunes
4
@WallyssonNunes Genau das habe ich geschrieben - "Lo-Dash, das Underscore erweitert, hat findIndex-Methode"
Splintor
3
Dies ist jetzt Teil der Standard-Unterstrichbibliothek ab Version 1.8.0: underscorejs.org/#1.8.0
Gage Trader
10

Wenn Ihre Zielumgebung ES2015 unterstützt (oder Sie einen Transpile-Schritt haben, z. B. mit Babel), können Sie den nativen Array.prototype.findIndex () verwenden.

Anhand Ihres Beispiels

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

Sie können die indexOfMethode von verwendenlodash

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
quelle
3

Halte es einfach:

// 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

Oder für Nicht-Hasser die CoffeeScript-Variante:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)
Joyrexus
quelle
1
besser wärereturn parseInt(i) for i, x of array when cond(x)
meagar
1
Wie ist das einfacher als frühere Antworten?
Ncubica
2

Dies soll den lodashBenutzern helfen . Überprüfen Sie, ob Ihr Schlüssel vorhanden ist, indem Sie Folgendes tun:

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

Die einfachste Lösung ist die Verwendung von lodash:

  1. Installiere lodash:

npm installieren - Lodash speichern

  1. Verwenden Sie die Methode findIndex:

const _ = require ('lodash');

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

Wenn Sie mehrere Übereinstimmungen erwarten und daher ein Array zurückgeben müssen, versuchen Sie Folgendes:

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

Wenn der Eigenschaftswert eindeutig ist und Sie den Index der Übereinstimmung benötigen, versuchen Sie Folgendes:

_.findWhere(Users, {_id: 10})
Ketan
quelle
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
quelle
0

Ich habe einen ähnlichen Fall, aber im Gegenteil ist es, den verwendeten Schlüssel basierend auf dem Index eines bestimmten Objekts zu finden. Ich konnte eine Lösung im Unterstrich finden, indem ich ein Object.valuesObjekt in ein Array zurückgab, um den aufgetretenen Index zu erhalten.

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
quelle