Warum hat JavaScript keine letzte Methode? [geschlossen]

124

Es ist schon komisch, dass die JavaScript-Array-Klasse keine letzte Methode zum Abrufen des letzten Elements eines Arrays bietet. Ich weiß, dass die Lösung einfach ist (Ar [Ar.length-1]), aber dennoch wird dies zu häufig verwendet.

Gibt es ernsthafte Gründe, warum dies noch nicht berücksichtigt wurde?

Nikhil Garg
quelle
39
In Fällen, in denen es Ihnen nichts ausmacht, das Array als Nebeneffekt zu ändern (dh wenn das Array ohnehin nur vorübergehend ist), lautet die Redewendung item= array.pop();.
Bobince
7
Hier ist ein Leistungsbenchmark für viele der genannten Methoden: jsperf.com/get-last-item-from-array
Web_Designer
5
Um Himmels willen, nachdem an diesem perf Seite suchen, scheint es , array[array.length-1]ist Weise schneller als die anderen.
Jondlm
@JondIm aber wenn Sie ein Array in Funktion erstellen, müssen Sie einen lokalen Namen dafür erfinden (was zu Namen wie arr2 führt), und Sie haben 2 Codezeilen anstelle von Oneliner
Danubian Sailor
1
(Ar[Ar.length-1])bekommt 20x bessere Leistung für mich.
Evgeni Sergeev

Antworten:

38

Weil sich Javascript sehr langsam ändert. Und das liegt daran, dass die Browser langsam aktualisiert werden.

Viele Javascript-Bibliotheken implementieren ihre eigene last()Funktion. Verwenden Sie eine!

Triptychon
quelle
20
Zumindest sollten Sie eine Bibliothek vorschlagen, die die Implementierung bereitstellt. Zum Beispiel ist Underscore.js eine gute Wahl. Siehe documentcloud.github.com/underscore/#last
Sean Lynch
11
@ Sean - Ich dachte, ich würde es vermeiden, dem Originalposter eine bestimmte Javascript-Bibliothek zu empfehlen. Google kann die kollektive Meinung des Webs zu der zu verwendenden Bibliothek ziemlich gut beurteilen. Warum sollte ich einen bestimmten vorschlagen? In der Tat, warum haben Sie underscore.js empfohlen, was mir auf den ersten Blick sehr geschmacklich erscheint?
Triptychon
6
Ich bevorzuge eigentlich die folgende Antwort, die Funktion außerhalb einer Bibliothek zu implementieren. Als jemand, der über Google auf diese Frage gestoßen ist, schlug ich vor, dass die beste Antwort anderen hilft, ihre Suche nach einer Lösung fortzusetzen, anstatt sie an die Schaltfläche "Zurück" zu senden.
Sean Lynch
5
Die Frage war "Warum ist diese Funktion nicht in Javascript integriert?" Und nicht "Wie kann diese Funktionalität erreicht werden?". Es gibt keinen Grund zu der Annahme, dass der ursprüngliche Autor nach einer Möglichkeit gesucht hat, seine eigene last()Funktion zu schreiben . Die Frage betraf die Art der Entwicklung der Javascript-Kernsprache selbst.
Triptychon
3
Aber wenn @Nikhil wissen will, wie man es implementiert - hat der Unterstrich eine wunderbare Quelle mit Anmerkungen. Diese Implementierung von last () ist ziemlich robust, wahrscheinlich mehr als von diesem Autor benötigt, aber großartig für eine Bibliothek. documentcloud.github.com/underscore/docs/…
Reconbot
264

Sie können so etwas tun:

[10, 20, 30, 40].slice(-1)[0]

Die Anzahl der Hilfsmethoden, die einer Sprache hinzugefügt werden können, ist unendlich. Ich nehme an, sie haben einfach nicht darüber nachgedacht, diesen hinzuzufügen.

Álvaro González
quelle
11
versucht, für "nahe der Unendlichkeit" zu stimmen
Triptychon
11
Warum? Sie können so nah kommen, wie Sie wollen, ohne Limit :)
Álvaro González
35
Dieser sollte die Antwort sein.
Giampaolo Rodolà
7
@UpTheCreek, da Sie das Array nicht in einer Variablen speichern müssen.
RMOBIS
5
@ ÁlvaroG.Vicario Dies ist in Ordnung für eine Reihe von Referenzen, aber in Ihrem Beispiel arbeiten Sie mit Zahlen. Gemäß MDN-Dokument: "Slice kopiert Zeichenfolgen und Zahlen in das neue Array. Änderungen an der Zeichenfolge oder Nummer in einem Array wirken sich nicht auf das andere Array aus." Wenn der Entwickler eine Referenz "array.last" erhalten möchte, um etwas mit dem Wert des letzten Elements in seinem ursprünglichen Array zu tun, und die Array-Werte zufällig Zeichenfolgen- oder Zahlenliterale sind, funktioniert diese Methode nicht.
1nfiniti
82

Es ist einfach, einen selbst zu definieren. Das ist die Stärke von JavaScript.

if(!Array.prototype.last) {
    Array.prototype.last = function() {
        return this[this.length - 1];
    }
}

var arr = [1, 2, 5];
arr.last(); // 5

Dies kann jedoch zu Problemen mit Code von Drittanbietern führen, der (fälschlicherweise) verwendet wird for..in Schleifen verwendet, um über Arrays zu iterieren.

Wenn Sie nicht mit jedoch gebunden sind Browser - Unterstützung Problemen, dann die neue ES5 - Syntax zu Eigenschaften zu definieren , diese Frage zu lösen, indem die Funktion nicht-zählbaren machen, etwa so:

Object.defineProperty(Array.prototype, 'last', {
    enumerable: false,
    configurable: true,
    get: function() {
        return this[this.length - 1];
    },
    set: undefined
});

var arr = [1, 2, 5];
arr.last; // 5
Anurag
quelle
11
Beachten Sie, dass das Hinzufügen von Eigenschaften zum Prototyp des Arrays den Code beschädigen kann, wobei for..in zum Iterieren über ein Array verwendet wird. Die Verwendung von for..in zum Iterieren eines Arrays ist eine schlechte Praxis, wird jedoch häufig genug durchgeführt, um das Ändern des Prototyps des Arrays ebenfalls zu praktizieren. Im Allgemeinen sollten Prototypen von Object, Array, String, Number, Boolean und Date nicht geändert werden, wenn Ihr Skript mit anderem unbekannten Code arbeiten muss.
Dagg Nabbit
7
@no - Danke für den Tipp. Ich hätte erwähnen sollen, dass der Grund für das Hinzufügen der ES5-Syntax mit der auf false eingestellten Aufzählbarkeit genau darin bestand, das for..inProblem zu lösen . Sicher, wir sind noch nicht mit einer umfassenden Implementierung von ES5 da, aber es ist gut genug, dies jetzt zu wissen, da Browser, einschließlich IE9, schnell aufholen.
Anurag
4
Bei leeren Listen wird this.length - 1ausgewertet -1, was, da es sich um eine negative Zahl handelt, als Array-Eigenschaft und nicht als Elementindex behandelt wird.
Claymation
26

i = [].concat(loves).pop(); //corn

Ikone Katze liebt Popcorn

Silviu-Marian
quelle
15
Warnung: Dadurch wird eine Kopie der gesamten Liste erstellt, um nur ein Element einzufügen. Möglicherweise zeitlich und räumlich sehr verschwenderisch. Tu es nicht.
Triptychon
13

Eine weitere Option, insbesondere wenn Sie bereits UnderscoreJS verwenden, ist:

_.last([1, 2, 3, 4]); // Will return 4
Pablo Diaz
quelle
5
Array.prototype.last = Array.prototype.last || function() {
    var l = this.length;
    return this[l-1];
}

x = [1,2];
alert( x.last() )
meder omuraliev
quelle
Was sollte für [] .last () angemessen ausgegeben werden? nulloder undefined?
Álvaro González
1
wahrscheinlich undefiniert, um es sprachlich konsistent zu halten.
Meder Omuraliev
null Ich denke, weil Sie ein gut definiertes Array haben, nur dass es keine gültigen Objekte enthält. undefined sollte nur verwendet werden, wenn die letzte 'Eigenschaft' für den aufgerufenen Container nicht definiert ist.
Nikhil Garg
3
this[l-1]Wenn Sie nur zurückkehren , erhalten Sie undefinedwie gewohnt Zugriff auf nicht vorhandene Eigenschaften. Persönlich würde JS lieber eine Ausnahme werfen als zurückkehren undefined, aber JS zieht es vor, Fehler unter den Teppich zu kehren.
Bobince
4

Kam hierher und suchte selbst nach einer Antwort auf diese Frage. Die Slice-Antwort ist wahrscheinlich die beste, aber ich habe eine "letzte" Funktion erstellt, um das Erweitern von Prototypen zu üben, also dachte ich, ich würde weitermachen und sie teilen. Es hat den zusätzlichen Vorteil gegenüber einigen anderen, dass Sie optional rückwärts durch das Array zählen und beispielsweise das vorletzte oder das vorletzte Element herausziehen können. Wenn Sie keine Anzahl angeben, wird standardmäßig 1 verwendet und das letzte Element herausgezogen.

Array.prototype.last = Array.prototype.last || function(count) {
    count = count || 1;
    var length = this.length;
    if (count <= length) {
        return this[length - count];
    } else {
        return null;
    }
};

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.last(); // returns 9
arr.last(4); // returns 6
arr.last(9); // returns 1
arr.last(10); // returns null
Daniel
quelle
Wenn Sie die Funktion des Funktionsnamens verwenden last(4)oder last(9)verlieren, dh; last
Prashanth Shyamprasad
3

Hier ist eine weitere einfachere Möglichkeit, letzte Elemente zu schneiden

 var tags = [1, 2, 3, "foo", "bar", "foobar", "barfoo"];
 var lastObj = tags.slice(-1);

lastObjist jetzt ["barfoo"].

Python macht das genauso und als ich versuchte, JS zu verwenden, hat es geklappt. Ich vermute, dass die Manipulation von Zeichenfolgen in Skriptsprachen genauso funktioniert.

Wenn Sie die letzten beiden Objekte in einem Array haben möchten,

var lastTwoObj = tags.slice(-2)

wird dir geben ["foobar", "barfoo"]und so weiter.

Prashant
quelle
@ Jakub Danke für die Bearbeitung. Ich habe das entscheidende negative Vorzeichen verpasst.
Prashant
Nein, lastObjwird enthalten ["barfoo"]. Warum sollte ich es auf jeden Fall tun, Array.prototype.slice.call(tagsanstatt nur tags.slice?
2

pop()Methode wird den letzten Wert herausspringen lassen. Das Problem ist jedoch, dass Sie den letzten Wert im Array verlieren

Prashanth Shyamprasad
quelle
-1

Ja oder einfach nur:

var arr = [1, 2, 5];
arr.reverse()[0]

Wenn Sie den Wert und keine neue Liste möchten.

TDahl
quelle
10
Ich
bin
3
Abgesehen davon, dass es langsam ist, hat es auch einen bösen Nebeneffekt, da das ursprüngliche Array umgekehrt ist.
Stephen Quan