Holen Sie sich das letzte Element in einem Array

1142

Hier ist mein bisheriger JavaScript-Code:

var linkElement = document.getElementById("BackButton");
var loc_array = document.location.href.split('/');
var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-2]))); 
linkElement.appendChild(newT);

Derzeit wird das vorletzte Element im Array von der URL übernommen. Ich möchte jedoch überprüfen, ob das letzte Element im Array vorhanden ist, "index.html"und in diesem Fall stattdessen das drittletzte Element abrufen.

Balexander
quelle

Antworten:

1225
if (loc_array[loc_array.length - 1] === 'index.html') {
   // do something
} else {
   // something else
}

Für den Fall, dass Ihr Server dieselbe Datei für "index.html" und "inDEX.htML" bereitstellt, können Sie auch Folgendes verwenden : .toLowerCase().

Möglicherweise möchten Sie dies jedoch nach Möglichkeit auf der Serverseite tun: Es ist sauberer und funktioniert für Personen ohne JS.

Aaron Harun
quelle
1051

Ich bin mir nicht sicher, ob es einen Nachteil gibt, aber das scheint ziemlich kurz zu sein:

arr.slice(-1)[0] 

oder

arr.slice(-1).pop()

Beide werden zurückgegeben, undefinedwenn das Array leer ist.

kritzikratzi
quelle
31
Destrukturierung ist auch schön:const [lastItem] = arr.slice(-1)
diachedelic
@ diachedelic das ist der schickste Weg! Genial!
Trufa
1
.pop()Entfernt das letzte Element, das das ursprüngliche Array ändert. Es ist nicht dasselbe wie einfach diesen Wert abzurufen.
Badrush
3
@Badrush Slice () erstellt ein neues Array mit einer Kopie eines einzelnen Elements, und Pop ändert nur diese Kopie. Das ursprüngliche Array bleibt unversehrt
kritzikratzi
Sie sollten jedoch vermeiden, neue Arrays zu erstellen, es sei denn, dieser Code wird nicht häufig aufgerufen. Andernfalls wird die Speicherbereinigung zusätzlich belastet und / oder der Browser verwendet mehr Speicher.
mvmn
259

Verwenden Sie Array.pop :

var lastItem = anArray.pop();

Wichtig : Dies gibt das letzte Element zurück und entfernt es aus dem Array

Mohawke
quelle
165

Eine kürzere Version von dem, was @chaiguy gepostet hat:

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

Das Lesen des -1-Index kehrt undefinedbereits zurück.

BEARBEITEN:

Heutzutage scheint die Präferenz darin zu bestehen, Module zu verwenden und zu vermeiden, den Prototyp zu berühren oder einen globalen Namespace zu verwenden.

export function last(array) {
    return array[array.length - 1];
}
Aram Kocharyan
quelle
8
Wenn es nicht offensichtlich ist, wie dies tatsächlich verwendet werden soll, ist hier ein Beispiel : var lastItem = [3,2,1,5].last();. Der Wert von lastItemist 5.
user128216
7
Diese Antwort ist richtig und auch recht sauber , aber (!!!) Eine Faustregel Javascript ist , dass Do NOT modify objects you Do NOT own. Dies ist aus vielen Gründen gefährlich, z. B. 1. Andere Entwickler in Ihrem Team können verwirrt sein, da diese Methode nicht Standard ist. 2. Bei einem Update in Bibliotheken oder sogar bei Verwendung einer niedrigeren oder höheren ECMAScript-Version kann es leicht zu VERLOREN kommen!
Farzad YZ
1
Für alle, die sich fragen, bricht dies Array.forEach (). Ich stimme immer noch zu, dass das Modifizieren von Prototypen nicht das Schlimmste ist, aber dieser ist schlecht.
Seph Reed
1
Imo gibt es kein so großes Problem beim Ändern Array.prototype, aber Sie sollten verwenden Object.assign(Array.prototype, 'last', { value: function () { … } });. Andernfalls wird die Eigenschaft aufgezählt.
雨伞 雨伞
70

Hier erfahren Sie, wie Sie es ohne Auswirkung auf das Original ARRAY erhalten

a = [1,2,5,6,1,874,98,"abc"];
a.length; //returns 8 elements

Wenn Sie pop () verwenden, wird Ihr Array geändert

a.pop();  // will return "abc" AND REMOVES IT from the array 
a.length; // returns 7

Sie können dies jedoch verwenden, damit es keine Auswirkungen auf das ursprüngliche Array hat:

a.slice(-1).pop(); // will return "abc" won't do modify the array 
                   // because slice creates a new array object 
a.length;          // returns 8; no modification and you've got you last element 
ucefkh
quelle
6
Sie sollten Slice (-1) .pop () ausführen, andernfalls kopieren Sie das gesamte Array (Sie müssen wirklich nur das letzte Element kopieren).
kritzikratzi
pop()Dann brauchen Sie das nicht : tun Sie es einfacharr.slice(-1)[0]
Christophe Marois
56

Der "sauberste" ES6-Weg (IMO) wäre:

const foo = [1,2,3,4];
const bar = [...foo].pop();

Dies vermeidet eine Mutation foo, wie dies der Fall .pop()wäre, wenn wir den Spread-Operator nicht verwendet hätten.
Das heißt, ich mag auch die foo.slice(-1)[0]Lösung.

ddd
quelle
1
Sie können auch das Array Destrukturierung verwenden , um es mehr ES6;) stackoverflow.com/a/46485581/31671
alex
36
Beachten Sie, dass diese Lösung eine Kopie des gesamten Arrays ausführt.
Brendan Annable
4
Es ist genauso unlesbar wie, .slice(-1)[0]aber es ist langsamer. .slice
Könnte
12
Das Kopieren des gesamten Arrays nur für "saubere" Syntax erscheint mir albern. Es sieht nicht einmal so schön aus
Jemar Jones
43

Ich würde lieber array.pop()als Indizes verwenden.

while(loc_array.pop()!= "index.html"){
}
var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length])));

Auf diese Weise erhalten Sie immer das Element vor index.html (vorausgesetzt, Ihr Array hat index.html als ein Element isoliert). Hinweis: Sie verlieren jedoch die letzten Elemente aus dem Array.

Pablo Mescher
quelle
38

Ich denke, wenn Sie nur das Element ohne entfernen erhalten möchten, ist dies einfacher:

arr.slice(-1)[0]

Hinweis: Wenn das Array leer ist (z. B. []), wird dies zurückgegeben undefined.

Übrigens ... ich habe die Leistung nicht überprüft, aber ich denke, es ist einfacher und sauberer zu schreiben

schrecklichWeb
quelle
Beachten Sie, dass a) dies nicht den letzten Wert zurückgibt, sondern ein Array mit dem letzten Element ( arr.slice(-1)[0] === arr[arr.length - 1]), und b) es langsam ist, weil es arrin ein neues Array kopiert wird ( Leistungsmessung siehe stackoverflow.com/a/51763533/2733244 ).
Wortwart
33

const [lastItem] = array.slice(-1);

Array.prototype.slice mit -1 kann verwendet werden, um ein neues Array zu erstellen, das nur das letzte Element des ursprünglichen Arrays enthält. Anschließend können Sie mithilfe der Destructuring Assignment eine Variable mit dem ersten Element dieses neuen Arrays erstellen.

const lotteryNumbers = [12, 16, 4, 33, 41, 22];
const [lastNumber] = lotteryNumbers.slice(-1);

console.log(lotteryNumbers.slice(-1));
// => [22]
console.log(lastNumber);
// => 22

Jamie Mason
quelle
30

Das Abrufen des letzten Elements eines Arrays kann mithilfe der Slice- Methode mit negativen Werten erreicht werden.

Mehr dazu lesen Sie hier unten.

var fileName = loc_array.slice(-1)[0];
if(fileName.toLowerCase() == "index.html")
{
  //your code...
}

Die Verwendung von pop () ändert Ihr Array, was nicht immer eine gute Idee ist.

Mohoch
quelle
1
Scheibe gibt ein Array, obwohl, so verwenden arr.slice(-1)[0], wie diese Antwort .
Cees Timmerman
4
Wenn die Leistung ein Problem darstellt, wissen Sie, dass diese Methode viel langsamer ist als array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres
29

Sie können dieses Muster verwenden ...

let [last] = arr.slice(-1);

Denken Sie daran, dass es ein neues Array erstellt, sodass es weniger effizient ist als andere Lösungen, aber es wird fast nie der Leistungsengpass Ihrer Anwendung sein.

Alex
quelle
25

Diese Frage gibt es schon lange, daher bin ich überrascht, dass niemand erwähnt hat, dass nur das letzte Element nach a wieder aufgesetzt wird pop().

arr.pop()ist genau so effizient wie arr[arr.length-1]und beide haben die gleiche Geschwindigkeit wie arr.push().

Daher können Sie davonkommen mit:

--- BEARBEITET [überprüfen Sie, dass thePopnicht undefinedvor dem Drücken] ---

let thePop = arr.pop()
thePop && arr.push(thePop)

--- END EDIT ---

Was auf diese reduziert werden kann (gleiche Geschwindigkeit [EDIT: aber unsicher!]):

arr.push(thePop = arr.pop())    //Unsafe if arr empty

Das ist doppelt so langsam wie arr[arr.length-1] , aber Sie müssen nicht mit einem Index herumspielen. Das ist an jedem Tag Gold wert.

Von den Lösungen, die ich ausprobiert habe, und in Vielfachen der Execution Time Unit (ETU) von arr[arr.length-1] :

[Methode] .............. [ETUs 5 Elemente] ... [ETU 1 Million Elemente]

arr[arr.length - 1]      ------> 1              -----> 1

let myPop = arr.pop()
arr.push(myPop)          ------> 2              -----> 2

arr.slice(-1).pop()      ------> 36             -----> 924  

arr.slice(-1)[0]         ------> 36             -----> 924  

[...arr].pop()           ------> 120            -----> ~21,000,000 :)

Die letzten drei Optionen werden INSBESONDERE [...arr].pop()mit zunehmender Größe des Arrays SEHR viel schlechter. Auf einem Computer ohne die Speicherbeschränkungen meines Computers wird [...arr].pop()wahrscheinlich das Verhältnis 120: 1 beibehalten. Trotzdem mag niemand ein Ressourcenschwein.

Paul Parker
quelle
3
Wenn das anfängliche Array leer sein kann, führt dieser Ansatz zu einem falschen Ergebnis und []wird zu [undefined]. Sie müssen Rückwärtsschub mit expliziter undefinedPrüfung schützen , so etwas wiemyPop !== undefined && arr.push(myPop)
dhilt
23

Wenn jemand das letzte Element auf einmal erhalten möchte, kann er / sie Folgendes verwenden Array#splice():

lastElement = document.location.href.split('/').splice(-1,1);

Hier besteht keine Notwendigkeit, die geteilten Elemente in einem Array zu speichern und dann zum letzten Element zu gelangen. Wenn das einzige Ziel darin besteht, das letzte Element zu erhalten, sollte dies verwendet werden.

Hinweis: Dadurch wird das ursprüngliche Array geändert, indem das letzte Element entfernt wird. Stellen Sie sich splice(-1,1)eine pop()Funktion vor, die das letzte Element öffnet.

user1144616
quelle
5
Gibt dies nicht das letzte Element in einem Array anstelle des letzten Elements selbst zurück?
2
@tozazaburo ist das nicht dasselbe?
Aram Kocharyan
5
Dies ändert das Array. Sie können Slice (-1) anstelle von Splice (-1) verwenden, um das ursprüngliche Array unberührt zu lassen. @AramKocharyan keine sein nicht, zu vergleichen ["hi"]vs "hi".
kritzikratzi
20

Für diejenigen, die keine Angst haben, den Array-Prototyp zu überladen (und mit Aufzählungsmaskierung sollten Sie es nicht sein):

Object.defineProperty( Array.prototype, "getLast", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        return this[ this.length - 1 ];
    }
} );
devios1
quelle
18

jQuery löst dies ordentlich:

> $([1,2,3]).get(-1)
3
> $([]).get(-1)
undefined
Cees Timmerman
quelle
18

Ich benutze normalerweise Unterstriche , damit kannst du es einfach machen

if (_.last(loc_array) === 'index.html'){
  etc...
}

Für mich ist das semantischer als loc_array.slice(-1)[0]

niels
quelle
18

Hier ist mehr Javascript-Kunst, wenn Sie hierher gekommen sind, um danach zu suchen

Im Geiste einer anderen Antwort, die verwendet wurde reduceRight(), aber kürzer:

[3, 2, 1, 5].reduceRight(a => a);

Dies hängt davon ab, dass für den Fall, dass Sie keinen Anfangswert angeben, das allerletzte Element als Anfangswert ausgewählt wird (siehe Dokumente hier ). Da der Rückruf immer wieder den Anfangswert zurückgibt, wird am Ende das letzte Element zurückgegeben.

Beachten Sie, dass dies als Javascript-Kunst betrachtet werden sollte und keineswegs die Art und Weise ist, wie ich es empfehlen würde, hauptsächlich, weil es in O (n) -Zeit ausgeführt wird, aber auch, weil es die Lesbarkeit beeinträchtigt.

Und jetzt zur ernsthaften Antwort

Der beste Weg, den ich sehe (wenn man bedenkt, dass Sie es prägnanter wollen als array[array.length - 1]), ist folgender:

const last = a => a[a.length - 1];

Dann nutzen Sie einfach die Funktion:

last([3, 2, 1, 5])

Die Funktion ist tatsächlich nützlich, wenn Sie mit einem anonymen Array wie dem [3, 2, 1, 5]oben verwendeten arbeiten, andernfalls müssten Sie es zweimal instanziieren, was ineffizient und hässlich wäre:

[3, 2, 1, 5][[3, 2, 1, 5].length - 1]

Pfui.

In diesem Fall haben Sie beispielsweise ein anonymes Array und müssten eine Variable definieren. Sie können jedoch Folgendes verwenden last():

last("1.2.3".split("."));
Lucio Paiva
quelle
16

Setzen Sie hier einfach eine andere Option.

loc_array.splice(-1)[0] === 'index.html'

Ich fand den obigen Ansatz sauberer und kurzer Onliner. Bitte zögern Sie nicht, dieses zu versuchen.

Hinweis: Das ursprüngliche Array wird geändert. Wenn Sie es nicht ändern möchten, können Sie es verwenden slice()

loc_array.slice(-1)[0] === 'index.html'

Vielen Dank an @VinayPai für den Hinweis.

Sidgujrathi
quelle
Laut dem Kommentar von stackoverflow.com/users/510036/qix-monica-was-mistreated in diesem Beitrag stackoverflow.com/questions/9050345/… und den Tests unter jsperf.com/last-array-element2 ist das extrem langsam
Subash
13

Mehrere Möglichkeiten, den letzten Wert eines Arrays in Javascript zu finden

  • Ohne das ursprüngliche Array zu beeinflussen

var arr = [1,2,3,4,5];

console.log(arr.slice(-1)[0])
console.log(arr[arr.length-1])
const [last] = [...arr].reverse();
console.log(last)
console.log(arr.reverse()[0])

  • Ändert das ursprüngliche Array

var arr = [1,2,3,4,5];

console.log(arr.pop())
arr.push(5)
console.log(...arr.splice(-1));

  • Durch Erstellen einer eigenen Hilfsmethode

let arr = [1, 2, 3, 4, 5];

Object.defineProperty(arr, 'last', 
{ get: function(){
  return this[this.length-1];
 }
})

console.log(arr.last);

Vahid Akhtar
quelle
Wenn Sie in Ihrem ersten Beispiel angeben, "ohne das ursprüngliche Array zu beeinflussen" und wie vorgeschlagen vorgehen: console.log(arr.reverse()[0]) - Herzlichen Glückwunsch, Sie haben gerade das ursprüngliche Array geändert.
Roko C. Buljan
12
const lastElement = myArray[myArray.length - 1];

Dies ist aus Sicht der Leistung die beste Option (~ 1000-mal schneller als arr.slice (-1)).

Alexander Burakevych
quelle
10

Persönlich würde ich die Antwort von kuporific / kritzikratzi positiv bewerten. Die Methode array [array.length-1] wird sehr hässlich, wenn Sie mit verschachtelten Arrays arbeiten.

var array = [[1,2,3], [4,5,6], [7,8,9]]

array.slice(-1)[0]

//instead of 

array[array.length-1]

//Much easier to read with nested arrays

array.slice(-1)[0].slice(-1)[0]

//instead of

array[array.length-1][array[array.length-1].length-1]
Michael Falck Wedelgård
quelle
10

Um zu verhindern, dass das letzte Element aus dem Ursprungsarray entfernt wird, können Sie es verwenden

Array.from(myArray).pop()

Wird meistens von allen Browsern unterstützt (ES6)

Alexandr Malinin
quelle
1
Viel Glück mit großen Arrays von 100.000 Elementen oder mehr.
Soldeplata Saketos
9

Sie können last()dem ArrayPrototyp eine Funktion hinzufügen .

Array.prototype.last = function () {
    return this[this.length - 1];
};
trinalbadger587
quelle
9

Was immer Sie tun nicht nur verwenden reverse()!!!

In einigen Antworten wird reversedie Tatsache erwähnt, aber nicht erwähnt, dass reversedas ursprüngliche Array geändert wird und keine Kopie (wie in einer anderen Sprache oder einem anderen Framework) zurückgegeben wird.

var animals = ['dog', 'cat'];

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

Dies kann die schlechteste Art von Code zum Debuggen sein!

Simon_Weaver
quelle
4
Wenn Sie eine umgekehrte Kopie Ihres Arrays wünschen , können Sie jetzt den Spread-Operator verwenden. zB[...animals].reverse()
Josh R
Sie können das Array einfach kopieren, bevor Sie reverse verwenden[1,3,4,5,"last"].slice().reverse()[0]
Madeo
9

Die Zerstörung von ES6-Objekten ist ein weiterer Weg.

const {length, [length-1]: last}=[1,2,3,4,5]
console.log(last)

Sie extrahieren die Längeneigenschaft mithilfe der Objektdestrukturierung aus dem Array. Sie erstellen einen weiteren dynamischen Schlüssel mit dem bereits extrahierten Schlüssel von [Länge-1] und weisen ihn dem letzten zu , alles in einer Zeile.

Gautamits
quelle
ein bisschen knifflig aber klug.
Adrien Castagliola
Danke, können Sie erklären, was genau es tut?
Tarun Nagpal
8

Sie können dem Prototyp von einen neuen Property Getter hinzufügen , damit auf alle Instanzen von zugegriffen werden kann .ArrayArray

Mit Getters können Sie auf den Rückgabewert einer Funktion zugreifen, als wäre es der Wert einer Eigenschaft. Der Rückgabewert der Funktion ist natürlich der letzte Wert des Arrays (this[this.length - 1] ).

Schließlich wickeln Sie es in eine Bedingung ein, die prüft, ob die lastEigenschaft noch vorhanden ist undefined(nicht durch ein anderes Skript definiert, das möglicherweise darauf angewiesen ist).

if(typeof Array.prototype.last === 'undefined') {
    Object.defineProperty(Array.prototype, 'last', {
        get : function() {
            return this[this.length - 1];
        }
    });
}

// Now you can access it like
[1, 2, 3].last;            // => 3
// or
var test = [50, 1000];
alert(test.last);          // Says '1000'

Funktioniert nicht in IE ≤ 8.

Matmarbon
quelle
Array.prototype.lastist immer undefined? Das if funktioniert nicht unter Chrome 36
bryc
7

EDITIERT:

Kürzlich habe ich eine weitere Lösung gefunden, die meiner Meinung nach die beste für meine Bedürfnisse ist:

function w(anArray) {
  return {
    last() {
      return anArray [anArray.length - 1];
    };
  };
}

Mit der obigen Definition kann ich jetzt sagen:

let last = w ([1,2,3]).last();
console.log(last) ; // -> 3

Der Name "w" steht für "Wrapper". Sie können sehen, wie Sie diesem Wrapper neben 'last ()' problemlos weitere Methoden hinzufügen können.

Ich sage "am besten für meine Bedürfnisse", weil ich auf diese Weise jedem integrierten JavaScript-Typ problemlos andere "Hilfsmethoden" hinzufügen kann. Was mir in den Sinn kommt, sind zum Beispiel das Auto () und das CDR () von Lisp.

Panu Logic
quelle
Warum einen Wrapper verwenden? Wenn Sie eine wFunktion aufrufen müssen, lassen Sie die Funktion einfach das letzte Element zurückgeben.
fregante
w([1,2,3]).lengthist nicht definiert. w([1,2,3])[1]ist nicht definiert. Kommt mir nicht wie ein Wrapper vor. Und es gibt einen Syntaxfehler. Sie haben ein zusätzliches ';'. Unter stackoverflow.com/a/49725374/458321 erfahren Sie, wie Sie einen Klassen-Wrapper (SutString-Klasse) schreiben und diesen Wrapper mithilfe von Reflection füllen. Imho, Wrapper sind allerdings übertrieben. Verwenden Sie besser die Kapselung, wie Sie es fast getan haben. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Außerdem ist w viel zu allgemein. Aufruf ist ArrayW oder so.
TamusJRoyce
6

Ich denke, der einfachste und ineffizienteste Weg ist:

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".
Osman Erdi
quelle
43
Diese Lösung benötigt O (n) mehr Speicher und benötigt O (n) Zeit. Es ist wirklich nicht die ideale Lösung.
hlin117