Articles

Wie findet man die maximale ID in einem Array von Objekten in JavaScript

Posted on

Ich habe vor kurzem ein Tutorial für einige Studenten zusammengestellt und bin auf ein Problem gestoßen, das wir sicher alle schon einmal hatten. Ich hatte dieses Array von Objekten und in jedem Objekt hatte ich eine ID. Ich wollte einen schnellen und effizienten Weg, um alle IDs zu betrachten und die maximale ID zu finden.

In diesem Artikel werde ich Sie durch 4 verschiedene Lösungen führen.

  • Array.forEach
  • Array.map
  • Array.reduce
  • Math.max

Projekt einrichten

Ich verwende Node, um dieses Beispiel auszuführen, aber Sie können genauso gut JavaScript verwenden und dies in eine Webseite einfügen. Das erste, was ich tun werde, ist, das Assert-Modul von Node zu benötigen, das uns die Möglichkeit gibt, einen einfachen Satz von Assertion-Tests bereitzustellen.

const assert = require("assert");

Als nächstes werden Sie ein Array von Zeichen erstellen. Ich habe vor kurzem das Buch Bad Blood gelesen, also habe ich beschlossen, einige der Charaktere aus diesem Buch zu verwenden. Nebenbei bemerkt: Wenn Sie das Buch noch nicht gelesen haben, kann ich es nur empfehlen. Jedes Zeichen im Array wird ein Objekt sein, das eine ID, einen Vornamen und einen Nachnamen enthält.

const characters = ;

In jeder möglichen Lösung wollen Sie eine Logik schreiben, die die größte ID im Array zurückgibt.

Array.forEach

Ihr erster Gedanke könnte sein, über das Array mit einer Art Schleife zu iterieren, und warum auch nicht, es ist das, was man Ihnen beigebracht hat, seit Sie angefangen haben, Code zu schreiben. Sie können beginnen, indem Sie einen Maximalwert von Null deklarieren, über jedes Zeichen iterieren und, wenn seine ID größer als der Maximalwert ist, den Maximalwert aktualisieren.

let max = 0;characters.forEach(character => { if (character.id > max) { max = character.id; }});assert(max === 444);

Mein Hauptziel ist es jedes Mal, wenn ich Code schreibe, etwas zuerst zum Laufen zu bringen und es dann später zu verbessern. Wenn Sie diesen Code ausführen würden, funktioniert er sicherlich, aber er erscheint mir einfach nicht richtig. Was ist, wenn Sie eintausend oder eine Million Objekte im Array haben? Jedes Mal, wenn ich anfange, über ein Array zu iterieren, indem ich irgendeine Art von Schleife verwende, um irgendeine Berechnung auszuführen, ist das für mich ein großes Warnsignal.

Array.map

Wann immer dieses Warnsignal der Iteration über ein Array auftaucht, frage ich mich sofort, ob das etwas ist, das map/filter/reduce lösen kann. Wenn Sie also diesen Ansatz wählen wollten, können Sie mit der map-Methode beginnen. Die map()-Methode erzeugt ein neues Array mit den Ergebnissen des Aufrufs einer bereitgestellten Funktion auf jedem Element im aufrufenden Array. Sie werden die map-Methode verwenden, um ein neues Array zu erstellen, das nur die Ids enthält, so dass Sie nicht mehr mit Objekten arbeiten. An diesem Punkt können Sie einfach die normale Sortiermethode auf das Array anwenden, sich das letzte Element in der Liste schnappen und das ist Ihre maximale ID.

const ids = characters.map(user => user.id);const sorted = ids.sort((a, b) => a - b);assert(sorted === 444);

Wenn Sie es richtig schick haben wollen, können Sie das alles in einer einzigen Anweisung machen.

assert( characters.map(user => user.id).sort((a, b) => a - b) === 444);

Array.reduce

Die reduce()-Methode führt eine Reducer-Funktion (die Sie bereitstellen) auf jedem Mitglied des Arrays aus, was zu einem einzigen Ausgabewert führt. Hier werden Sie reduce auf dem Array characters aufrufen. Sie werden einen Akkumulator definieren, der den Rückgabewert des Callbacks akkumuliert. Jedes Mal, wenn die Callback-Funktion aufgerufen wird, gibt sie einen Wert zurück und speichert ihn in max. Die Callback-Methode schaut sich die Zeichen-ID an und wenn sie größer als max ist, gibt sie das zurück, wenn nicht, gibt sie max zurück. Schließlich muss ein Standardwert für max gesetzt werden, und das macht characters.id.

const maxId = characters.reduce( (max, character) => (character.id > max ? character.id : max), characters.id);assert(maxId === 444);

Wie Sie sehen, ist dies ein ähnlicher Ansatz wie die forEach-Methode, die jedes Element durchläuft und es mit max vergleicht. Der Unterschied hier ist, dass die Verwendung von reduce viel schneller ist. Sie können auch eine Kombination aus reduce und der nächsten Lösung Math.max() verwenden, wenn Sie das möchten.

Der Spread-Operator

Während mir der Ansatz von map und reduce viel besser gefällt als das Iterieren über das Array, fühlt es sich für mich immer noch nicht gut an. Wenn Sie sich in Math.max vertiefen, werden Sie herausfinden, dass es eine Liste von Zahlen oder ein Array von Zahlen annehmen kann.

Das bedeutet, dass Sie nur ein Array von Id’s erhalten müssen und dieses an die max() Funktion übergeben können. Wenn Sie gut aufgepasst haben, haben Sie das schon früher mit map gemacht. Das bedeutet, dass Sie die map-Funktion verwenden können, um ein Array von Ids zu erhalten und es dann mit dem Spread-Operator an die max()-Funktion zu übergeben.

assert(Math.max(...characters.map(user => user.id)) === 444);

Die Spread-Syntax erlaubt es, eine Iterable wie einen Array-Ausdruck oder eine Zeichenkette an Stellen zu expandieren, an denen null oder mehr Argumente (bei Funktionsaufrufen) oder Elemente (bei Array-Literalen) erwartet werden, oder ein Objektausdruck kann an Stellen erweitert werden, an denen null oder mehr Schlüssel-Wert-Paare (für Objektliterale) erwartet werden.

Dies ist für mich die am saubersten aussehende Lösung, und sie gefällt mir sehr gut.

Leistungsergebnisse

Ich wollte dies nicht zu einem Artikel über funktionale Programmierung in JavaScript machen, aber hier sind wir gelandet. Ich habe ein paar grundlegende Zeitmessungen für jede der Funktionen durchgeführt (mit console.time() &console.timeEnd()) und die folgenden Ergebnisse gefunden.

  • Iterate test: 0.217ms
  • Map-Test: 0.191ms
  • reduce test: 0.144ms
  • spread test: 0.148ms

Fazit

Während die Verwendung von reduce uns einen kleinen Leistungsvorteil verschaffte, bevorzuge ich hier die Verwendung von Math.max und dem Spread-Operator. Für mich sieht es einfach sauberer aus und es ist etwas, das ich gerne schreibe. Wenn Sie dieses Problem hätten, zu welcher Lösung würden Sie greifen? Übersehe ich etwas? Ich hoffe, es hat Ihnen Spaß gemacht, durchzugehen, wie ich dieses Problem lösen würde und bis zum nächsten Mal…

Happy CodingDan

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.