Monkeypatching Math.min für JavaScript Arrays

Im Rahmen eines Computertutoriums stand ich vor dem Problem, das Minimum eines Arrays bestimmen zu wolle. Samt Index im Idealfall.

Leider geht das nicht ohne Weiteres. Von daher beschreibe ich hier eine Lösung.

Zunächst ein kurzer Ausflug in die Geschichte, warum die Standard-Bibliothek von JavaScript so umständlich aussieht.

Hey, JavaScript is pretty cool, who knew?
Flickr: Hey, JavaScript is pretty cool, who knew?
von J. Albert Bowden II (CC-BY)

 

JavaScript ist intern bei Netscape entstanden. Entwickelt von Brendan Eich (ja, der war kurz CEO von Mozilla). Von daher hat dieser Browser auch anfangs die beste Unterstützung gehabt.

Zu der Zeit war das Literal [] für Arrays noch nicht eingeführt worden. Diese mussten also per new Array erzeugt werden. Ganz am Anfang konnte Math.max bzw. Math.min sogar nur einen Wert aus genau zwei Argumenten wählen! Mittlerweile kann die Funktion beliebig viele Argumente entgegennehmen (d.h. sie sind variadische Funktionen geworden). Trotzdem sieht der Befehl wörtlich so aus:

Math.min.apply(Math, [1, 2, 3.4, 5]);

Es gibt allerdings einen Unterschied zwischen beliebig vielen Argumenten und ein Array mit beliebig vielen Werten als Argument. Von daher hier ohne Umschweife mein Monkeypatch:

var standardMin = Math.min;
Math.min = function() {
    if(Array.isArray(arguments[0])) {
        return standardMin.apply(Math, arguments[0]);
    } else {
        return standardMin(arguments[0]);
    }
};

Es stellt sich heraus, dass die eingebaute Funktionen wahnsinnig schnell sind!

Fehlt also nur noch der Index des kleinsten Wertes. Hier bietet sich JavaScripts Array.indexOf() an:

var arr = [1, 2, 3.4, 5];
var min = Math.min(arr);
var ind = arr.indexOf(Math.min(arr));

Anmerkung: Es geht natürlich noch schneller, d.h. statt wie hier O(2n) nur O(n) Schritte zu durchlaufen, wobei n die Länge des Arrays ist. Für mein Anwendungsfall wollte ich jetzt aber nicht beides in einer for-Schleife erschlagen. Die Optimierung lohnt sich einfach nicht.

Ach ja, Mozilla experimentiert übrigens mit einem neuen Operator namens “Spread” herum. Könnte hier auch wirksam werden …

Habt ihr Verbesserungsvorschläge? Teilt sie doch in den Kommentaren!

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s