Zdobądź ostatni element w tablicy


1142

Oto mój kod JavaScript do tej pory:

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);

Obecnie trwa od drugiego do ostatniego elementu w tablicy z adresu URL. Chcę jednak sprawdzić, czy ma być ostatni element w tablicy, "index.html"a jeśli tak, to zamiast tego złap trzeci.

Odpowiedzi:


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

W przypadku, gdy serwer służy do tego samego pliku na „index.html” i „index.html” można również użyć: .toLowerCase().

Chociaż możesz rozważyć zrobienie tego po stronie serwera, jeśli to możliwe: będzie czystsze i będzie działać dla osób bez JS.


1050

Nie jestem pewien, czy istnieje wada, ale wydaje się to dość zwięzłe:

arr.slice(-1)[0] 

lub

arr.slice(-1).pop()

Oba powrócą, undefinedjeśli tablica jest pusta.


31
fajne jest też użycie destrukcji:const [lastItem] = arr.slice(-1)
diachedelic

@diachedelic to najsprytniejszy sposób! Niesamowite!
Trufa

1
.pop()usuwa ostatni element, który modyfikuje oryginalną tablicę. To nie to samo, co zwykłe wyszukiwanie tej wartości.
Badrush

3
@Badrush slice () tworzy nową tablicę z kopią jednego elementu, a pop modyfikuje tylko tę kopię. pierwotna tablica pozostaje nienaruszona
kritzikratzi

Należy jednak unikać tworzenia nowych tablic, chyba że ten kod nie jest często wywoływany. W przeciwnym razie spowoduje to dodatkowe obciążenie w zakresie wyrzucania elementów bezużytecznych i / lub zwiększy wykorzystanie pamięci przez przeglądarkę.
mvmn


165

Krótsza wersja tego, co opublikował @chaiguy:

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

Odczytywanie indeksu -1 undefinedjuż powraca .

EDYTOWAĆ:

Obecnie preferuje się używanie modułów i unikanie dotykania prototypu lub korzystania z globalnej przestrzeni nazw.

export function last(array) {
    return array[array.length - 1];
}

8
Jeśli nie jest to oczywiste, jak to ma być rzeczywiście używany, oto przykład: var lastItem = [3,2,1,5].last();. Wartość lastItemwynosi 5.
user128216,

7
Ta odpowiedź jest poprawna, a także całkiem czysta, ALE (!!!) Podstawową zasadą jest używanie Javascript Do NOT modify objects you Do NOT own. Jest to niebezpieczne z wielu powodów, takich jak: 1. Inni programiści pracujący w twoim zespole mogą się pomylić, ponieważ ta metoda nie jest standardowa 2. przy każdej aktualizacji bibliotek lub nawet przy użyciu niższej lub wyższej wersji ECMAScript może łatwo UTRACIĆ!
Farzad YZ

1
Dla każdego, kto się zastanawia, powoduje to uszkodzenie Array.forEach (). Nadal zgadzam się, że modyfikowanie prototypów nie jest najgorszą rzeczą, ale ta jest zła.
Seph Reed

1
Imo nie ma tak dużego problemu z modyfikacją Array.prototype, ale powinieneś użyć Object.assign(Array.prototype, 'last', { value: function () { … } });. W przeciwnym razie właściwość będzie policzalna.
黄 雨伞


70

Oto, jak go uzyskać bez wpływu na oryginalną tablicę

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

Jeśli użyjesz pop (), zmodyfikuje twoją tablicę

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

Ale możesz użyć tego, aby nie miało to wpływu na oryginalną tablicę:

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 

6
powinieneś zrobić slice (-1) .pop (), w przeciwnym razie skopiujesz całą tablicę (tak naprawdę wystarczy skopiować ostatni element).
kritzikratzi

Nie ma takiej potrzeby pop(): po prostu zróbarr.slice(-1)[0]
Christophe Marois,

56

„Najczystszym” sposobem ES6 (IMO) byłoby:

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

Pozwala to uniknąć mutacji foo, tak jak .pop()by to było, gdybyśmy nie korzystali z operatora rozprzestrzeniania.
To powiedziawszy, podoba mi się również foo.slice(-1)[0]rozwiązanie.


1
Możesz także użyć restrukturyzacji tablicy, aby uczynić ją bardziej ES6;) stackoverflow.com/a/46485581/31671
alex

36
Zauważ, że to rozwiązanie wykonuje kopię całej tablicy.
Brendan Annable,

4
Jest tak samo nieczytelny jak, .slice(-1)[0]ale wolniejszy. .slice
Równie

12
Kopiowanie całej tablicy tylko dla „czystej” składni wydaje mi się głupie. To nawet nie wygląda tak ładnie
Jemar Jones,

43

Wolałbym używać array.pop()niż indeksów.

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

w ten sposób zawsze otrzymujesz element poprzedzający index.html (pod warunkiem, że twoja tablica ma izolowany index.html jako jeden element). Uwaga: jednak stracisz ostatnie elementy z tablicy.


38

Myślę, że jeśli chcesz tylko uzyskać element bez usuwania, to jest prostsze użyj tego:

arr.slice(-1)[0]

Uwaga: Jeśli tablica jest pusta (np. []), Funkcja zwróciundefined .

nawiasem mówiąc ... nie sprawdziłem wydajności, ale myślę, że jest prostszy i czystszy do napisania


Zauważ, że a) to nie zwraca ostatniej wartości, ale tablica z ostatnim elementem ( arr.slice(-1)[0] === arr[arr.length - 1]), i b) jest powolna, ponieważ kopiuje arrsię do nowej tablicy (zobacz stackoverflow.com/a/51763533/2733244 w celu pomiaru wydajności).
wortwart

33

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

Array.prototype.slice z -1 można użyć do utworzenia nowej tablicy zawierającej tylko ostatni element oryginalnej tablicy, a następnie można użyć Przypisania do restrukturyzacji, aby utworzyć zmienną przy użyciu pierwszego elementu tej nowej tablicy.

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

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


30

Uzyskanie ostatniego elementu tablicy można osiągnąć za pomocą wycinka metody z wartościami ujemnymi.

Więcej na ten temat możesz przeczytać tutaj na dole.

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

Użycie pop () zmieni tablicę, co nie zawsze jest dobrym pomysłem.


1
Kawałek zwraca tablicę, choć, więc użytku arr.slice(-1)[0], jak tej odpowiedzi .
Cees Timmerman

4
Jeśli wydajność stanowi problem, wiedz, że ta metoda jest znacznie wolniejsza niż array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres

29

Możesz użyć tego wzoru ...

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

Choć brzmi to dość ładnie, należy pamiętać, że tworzy nową tablicę więc jest mniej wydajny niż inne rozwiązania, ale prawie nigdy nie będzie gardłem wydajności aplikacji.


25

To pytanie było już dawno, więc jestem zaskoczony, że nikt nie wspomniał o ponownym włączeniu ostatniego elementu po pop() .

arr.pop()jest dokładnie tak samo wydajny, jak arr[arr.length-1]i oba mają taką samą prędkość jak arr.push().

Dlatego możesz uciec od:

--- EDYTOWANE [sprawdź, thePopczy nie jest undefinedprzed pchaniem] ---

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

--- EDYCJA KOŃCOWA ---

Co można zredukować do tej samej prędkości (ta sama prędkość [EDYCJA: ale niebezpieczne!]):

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

Jest to dwa razy wolniejsze niż arr[arr.length-1], ale nie musisz wypełniać indeksu. To jest warte złota każdego dnia.

Rozwiązań, które wypróbowałem oraz w wielokrotności jednostki czasu wykonania (ETU) arr[arr.length-1]:

[Metoda] .............. [ETU 5 elementów] ... [ETU 1 milion elementów]

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 :)

Ostatnie trzy opcje, W SZCZEGÓLNOŚCI [...arr].pop(), stają się BARDZO gorsze wraz ze wzrostem wielkości tablicy. Na komputerze bez ograniczeń pamięci mojego komputera [...arr].pop()prawdopodobnie zachowuje coś w rodzaju współczynnika 120: 1. Mimo to nikt nie lubi wieprza zasobów.


3
Jeśli tablica początkowa może być pusta, to podejście będzie niepoprawne i []zostanie zmienione [undefined]. Musisz chronić pchnięcie do tyłu za pomocą jawnej undefinedkontroli, coś w stylumyPop !== undefined && arr.push(myPop)
dhilt

23

Jeśli ktoś chce uzyskać ostatni element za jednym razem, może użyć Array#splice():

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

W tym przypadku nie ma potrzeby przechowywania podzielonych elementów w tablicy, a następnie przejścia do ostatniego elementu. Jeśli zdobycie ostatniego elementu jest jedynym celem, należy to wykorzystać.

Uwaga: Zmienia to oryginalną tablicę poprzez usunięcie jej ostatniego elementu. Myśleć splice(-1,1)jako pop()funkcji, które pojawia ostatni element.


5
Czy to nie zwraca ostatniego elementu w tablicy, zamiast samego ostatniego elementu?

2
@tozazaburo to nie to samo?
Aram Kocharyan

5
to modyfikuje tablicę. możesz użyć wycinka (-1) zamiast splajnu (-1), aby pozostawić oryginalną tablicę nietkniętą. @AramKocharyan No nie jego, porównaj ["hi"]vs "hi".
kritzikratzi

20

Dla tych, którzy nie boją się przeciążać prototypu Array (a przy maskowaniu wyliczeń nie powinieneś być):

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


18

Zazwyczaj używam podkreślników , dzięki którym możesz po prostu zrobić

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

Dla mnie jest to bardziej semantyczne niż loc_array.slice(-1)[0]


18

Oto więcej sztuki Javascript, jeśli tu przyszedłeś jej szukać

W duchu innej odpowiedzi, która została użyta reduceRight(), ale krótsza:

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

Opiera się na fakcie, że jeśli nie podasz wartości początkowej, ostatni element jest wybierany jako element początkowy (sprawdź tutaj dokumenty ). Ponieważ wywołanie zwrotne po prostu zwraca wartość początkową, ostatni element będzie zwracany na końcu.

Uważaj, że należy to uznać za sztukę Javascript i nie jest to sposób, w jaki poleciłbym to zrobić, głównie dlatego, że działa w czasie O (n), ale także dlatego, że szkodzi czytelności.

A teraz poważna odpowiedź

Najlepszy sposób, jaki widzę (biorąc pod uwagę, że chcesz bardziej zwięzły niż array[array.length - 1]), to:

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

Następnie wystarczy użyć funkcji:

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

Ta funkcja jest przydatna w przypadku, gdy masz do czynienia z anonimową tablicą, taką jak [3, 2, 1, 5]używana powyżej, w przeciwnym razie musiałbyś utworzyć ją dwukrotnie, co byłoby nieefektywne i brzydkie:

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

Ugh.

Na przykład, oto sytuacja, w której masz anonimową tablicę i musisz zdefiniować zmienną, ale last()zamiast tego możesz użyć :

last("1.2.3".split("."));

16

Po prostu umieszczam tutaj inną opcję.

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

Uważam, że powyższe podejście jest bardziej czyste i krótkie onliner. Proszę, spróbuj tego.

Uwaga: zmodyfikuje oryginalną tablicę, jeśli nie chcesz jej modyfikować, możesz jej użyć slice()

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

Dzięki @VinayPai za zwrócenie na to uwagi.



13

Wiele sposobów na znalezienie ostatniej wartości tablicy w javascript

  • Bez wpływu na oryginalną tablicę

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])

  • Modyfikuje oryginalną tablicę

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

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

  • Tworząc własną metodę pomocniczą

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

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

console.log(arr.last);


Jeśli twoim pierwszym przykładem jest „Bez wpływu na oryginalną tablicę” i postępując zgodnie z sugestią: console.log(arr.reverse()[0]) - gratulacje, właśnie zmodyfikowałeś oryginalną tablicę.
Roko C. Buljan

12
const lastElement = myArray[myArray.length - 1];

To najlepsze opcje z punktu widzenia wydajności (~ 1000 razy szybciej niż arr.slice (-1)).


10

Osobiście głosowałbym za odpowiedzią kuporific / kritzikratzi. Metoda array [array.length-1] staje się bardzo brzydka, jeśli pracujesz z zagnieżdżonymi tablicami.

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]


10

Aby zapobiec usunięciu ostatniego elementu z tablicy pochodzenia, możesz użyć

Array.from(myArray).pop()

Obsługiwany głównie przez wszystkie przeglądarki (ES6)


1
powodzenia z dużymi tablicami zawierającymi 100 000 lub więcej elementów.
Soldeplata Saketos

9

Możesz dodać last()funkcję do Arrayprototypu.

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

9

Cokolwiek robisz, nie tylko używajreverse() !!!

Kilka odpowiedzi wspomina, reverseale nie wspomina o tym, że reversemodyfikuje oryginalną tablicę i nie zwraca (jak w innym języku lub frameworku) kopii.

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

To może być najgorszy typ kodu do debugowania!


4
Jeśli chcesz odwrócić kopię tablicy, możesz teraz użyć operatora rozkładania. np.[...animals].reverse()
Josh R

możesz po prostu skopiować tablicę przed użyciem wstecznej[1,3,4,5,"last"].slice().reverse()[0]
Madeo

9

Restrukturyzacja obiektów ES6 to kolejna droga.

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

Wyodrębniasz właściwość length z tablicy za pomocą destrukcji obiektu. Tworzysz kolejny klucz dynamiczny, używając już wyodrębnionego klucza przez [length-1] i przypisujesz go do końca , wszystko w jednym wierszu.


trochę trudne, ale sprytne.
Adrien Castagliola

Dzięki, możesz wyjaśnić, co dokładnie robi?
Tarun Nagpal

8

Możesz dodać nowy getter właściwości do prototypuArray , aby był dostępny we wszystkich instancjachArray .

Gettery umożliwiają dostęp do wartości zwracanej przez funkcję tak, jakby to była wartość właściwości. Zwracana wartość funkcji jest oczywiście ostatnią wartością tablicy (this[this.length - 1] ).

Na koniec lastowijamy go w warunek, który sprawdza, czy właściwość -prop nadal jest undefined(nie zdefiniowana przez inny skrypt, który może na niej polegać).

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'

Nie działa w IE ≤ 8.


Array.prototype.lastjest zawsze undefined? The if nie działa pod Chrome 36
bryc

7

EDYTOWANE:

Ostatnio wymyśliłem jeszcze jedno rozwiązanie, które moim zdaniem jest najlepsze dla moich potrzeb:

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

Dzięki powyższej definicji mogę teraz powiedzieć:

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

Nazwa „w” oznacza „opakowanie”. Możesz zobaczyć, jak możesz łatwo dodać do tego opakowania więcej metod niż „last ()”.

Mówię „najlepiej dla moich potrzeb”, ponieważ pozwala mi to łatwo dodawać inne takie „metody pomocnicze” do każdego wbudowanego typu JavaScript. Na myśl przychodzi na przykład car () i cdr () z Lisp.


Dlaczego warto korzystać z owijarki? Jeśli musisz wywołać wfunkcję, po prostu spraw, aby funkcja zwróciła ostatni element.
fregante

w([1,2,3]).lengthjest niezdefiniowany. w([1,2,3])[1]jest niezdefiniowany. Nie wygląda mi to na opakowanie. I jest błąd składniowy. Masz dodatkowe „;”. Zobacz stackoverflow.com/a/49725374/458321, aby dowiedzieć się, jak napisać opakowanie klasy (klasa SutString) i użyć refleksji, aby wypełnić to opakowanie. Chociaż, imho, opakowania są przesadzone. Lepiej używać enkapsulacji, jak prawie masz. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Ponadto w jest zbyt ogólne. Call to ArrayW lub coś takiego.
TamusJRoyce,

6

Myślę, że najłatwiejszym i najbardziej nieefektywnym sposobem jest:

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".

43
To rozwiązanie zajmuje O (n) więcej pamięci i zajmuje O (n) czas. To naprawdę nie jest idealne rozwiązanie.
hlin117,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.