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?



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


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


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.


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.


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

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

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)

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

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

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

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

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.