530 Stimmen

Holen Sie sich den Index des Objekts in einem Array, das einer Bedingung entspricht

Ich habe ein Array wie dieses:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]

Wie kann ich den Index des Objekts erhalten, das einer Bedingung entspricht, ohne das gesamte Array zu durchlaufen?

Zum Beispiel, gegeben prop2=="yutu", möchte ich den Index 1 erhalten.

Ich habe .indexOf() gesehen, aber ich denke, es wird für einfache Arrays wie ["a1","a2",...] verwendet. Ich habe auch $.grep() überprüft, aber das gibt Objekte zurück, nicht den Index.

1157voto

georg Punkte 205206

Ab 2016 sollten Sie dafür Array.findIndex (ein ES2015/ES6-Standard) verwenden:

a = [
  {prop1:"abc",prop2:"qwe"},
  {prop1:"bnmb",prop2:"yutu"},
  {prop1:"zxvz",prop2:"qwrq"}];

index = a.findIndex(x => x.prop2 ==="yutu");

console.log(index);

Es wird von Google Chrome, Firefox und Edge unterstützt. Für den Internet Explorer gibt es ein Polyfill auf der verlinkten Seite.

Leistungshinweis

Funktionsaufrufe sind teuer, daher wird bei wirklich großen Arrays eine einfache Schleife viel besser als findIndex ausgeführt:

let test = [];

for (let i = 0; i < 1e6; i++)
    test.push({prop: i});

let search = test.length - 1;
let count = 100;

console.time('findIndex/vordefinierte Funktion');
    let fn = obj => obj.prop === search;

    for (let i = 0; i < count; i++)
        test.findIndex(fn);
console.timeEnd('findIndex/vordefinierte Funktion');

console.time('findIndex/dynamische Funktion');
    for (let i = 0; i < count; i++)
        test.findIndex(obj => obj.prop === search);
console.timeEnd('findIndex/dynamische Funktion');

console.time('Schleife');
    for (let i = 0; i < count; i++) {
        for (let index = 0; index < test.length; index++) {
            if (test[index].prop === search) {
                break;
            }
        }
    }
console.timeEnd('Schleife');

Wie bei den meisten Optimierungen sollte dies sorgfältig und nur dann angewendet werden, wenn es wirklich erforderlich ist.

32voto

T.J. Crowder Punkte 948310

Wie bekomme ich den Index des Objekts, das eine Bedingung erfüllt (ohne das Array zu durchlaufen)?

Du kannst das nicht, etwas muss mindestens einmal durch das Array iterieren.

Wenn sich die Bedingung häufig ändert, musst du durchlaufen und die Objekte darin anschauen, um zu sehen, ob sie die Bedingung erfüllen. Allerdings kann auf einem System mit ES5-Funktionen (oder wenn du ein Shim installierst) diese Iteration recht prägnant durchgeführt werden:

var index;
yourArray.some(function(entry, i) {
    if (entry.prop2 == "yutu") {
        index = i;
        return true;
    }
});

Dies verwendet die neue(ish) Array#some Funktion, die sich durch die Einträge im Array durchläuft, bis die von dir übergebene Funktion true zurückgibt. Die von mir übergebene Funktion speichert den Index des übereinstimmenden Eintrags und gibt dann true zurück, um die Iteration zu stoppen.

Oder natürlich kannst du einfach eine for-Schleife verwenden. Deine verschiedenen Möglichkeiten zur Iteration sind in dieser anderen Antwort abgedeckt.

Aber wenn du immer dieselbe Eigenschaft für die Suche verwenden wirst und wenn die Eigenschaftswerte eindeutig sind, kannst du nur einmal durchlaufen und ein Objekt erstellen, um sie zu verknüpfen:

var prop2map = {};
yourArray.forEach(function(entry) {
    prop2map[entry.prop2] = entry;
});

(Oder du könntest wieder eine for-Schleife verwenden oder eine deiner anderen Möglichkeiten aus deinen anderen Optionen.)

Dann, wenn du den Eintrag mit prop2 = "yutu" finden musst, kannst du folgendes tun:

var entry = prop2map["yutu"];

Ich nenne dies "cross-indexing" des Arrays. Natürlich musst du dein Zuordnungsobjekt aktualisieren, wenn du Einträge entfernst oder hinzufügst (oder ihre prop2-Werte änderst).

28voto

aliak Punkte 418

Was TJ Crowder sagte, jeder Weg wird irgendeine Art von versteckter Iteration haben, mit lodash wird das wie folgt:

var index = _.findIndex(array, {prop2: 'yutu'})

19voto

David Castro Punkte 1417
var CarId = 23;

//x.VehicleId property to match in the object array
var carIndex = CarsList.map(function (x) { return x.VehicleId; }).indexOf(CarId);

Und für grundlegende Elemente von Arrays können Sie auch dies tun:

var numberList = [100,200,300,400,500];
var index = numberList.indexOf(200); // 1

Sie erhalten -1, wenn der Wert im Array nicht gefunden werden kann.

13voto

Nina Scholz Punkte 348155
var index;
yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' ? (index = i, true) : false;
});

Gehe über alle Elemente des Arrays iterieren. Es gibt entweder den Index und true zurück oder false, wenn die Bedingung nicht erfüllt ist.

Wichtig ist der explizite Rückgabewert von true (oder ein Wert, dessen boolesches Ergebnis true ist). Die einfache Zuweisung ist nicht ausreichend, da es möglicherweise einen Index mit 0 gibt (Boolean(0) === false), was nicht zu einem Fehler führen würde, aber das Beenden der Iteration verhindert.

Bearbeiten

Eine noch kürzere Version des oben Gesagten:

yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' && ~(index = i);
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X