Obtenga el último elemento en una matriz


1142

Aquí está mi código JavaScript hasta ahora:

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

Actualmente, toma el penúltimo elemento de la matriz desde la URL. Sin embargo, quiero hacer una comprobación del último elemento de la matriz "index.html"y, de ser así, tomar el tercer al último elemento.

Respuestas:


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

En el caso de que el servidor sirve el mismo archivo para "index.html" y "index.html" también se puede utilizar: .toLowerCase().

Sin embargo, es posible que desee considerar hacer este lado del servidor si es posible: será más limpio y funcionará para personas sin JS.


si solo necesitas el último artículo, puedes hacerlo Array.pop ()
Badri Derakhshan hace

1052

No estoy seguro si hay un inconveniente, pero esto parece bastante conciso:

arr.slice(-1)[0] 

o

arr.slice(-1).pop()

Ambos volverán undefinedsi la matriz está vacía.


32
usar la desestructuración también es bueno:const [lastItem] = arr.slice(-1)
diachedelic

@diachedelic esta es la mejor manera! ¡Increíble!
Trufa

2
.pop()elimina el último elemento que modifica la matriz original. No es lo mismo que simplemente recuperar ese valor.
Badrush

44
@Badrush slice () crea una nueva matriz con una copia de un solo elemento, y pop modifica solo esa copia. la matriz original permanece ilesa
kritzikratzi

Pero debe evitar crear nuevas matrices a menos que este código no se llame con frecuencia. De lo contrario, supondrá un esfuerzo adicional para la recolección de basura y / o hará que el navegador use más memoria.
mvmn

259

Utilice Array.pop :

var lastItem = anArray.pop();

Importante : Esto devuelve el último elemento y lo elimina de la matriz.


165

Una versión más corta de lo que publicó @chaiguy:

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

Leer el índice -1 undefinedya regresa .

EDITAR:

En estos días, la preferencia parece ser el uso de módulos y evitar tocar el prototipo o usar un espacio de nombres global.

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

8
Si no es obvio cómo esto se va a usar en realidad, he aquí un ejemplo: var lastItem = [3,2,1,5].last();. El valor de lastItemes 5.
user128216

77
Esta respuesta es correcta y también bastante limpia PERO (!!!) Una regla general que usa Javascript es esa Do NOT modify objects you Do NOT own. Es peligroso por muchas razones, como 1. Otros desarrolladores que trabajan en su equipo podrían confundirse ya que este método no es estándar 2. Con cualquier actualización en las bibliotecas o incluso utilizando una versión ECMAScript inferior o superior, ¡podría PERDERse fácilmente!
Farzad YZ

1
Para cualquiera que se pregunte, esto rompe Array.forEach (). Todavía estoy de acuerdo en que modificar prototipos no es lo peor, pero este es malo.
Seph Reed

1
Imo, no hay un gran problema con la modificación Array.prototype, pero debes usarlo Object.assign(Array.prototype, 'last', { value: function () { … } });. De lo contrario, la propiedad será enumerable.
雨伞 雨伞


70

Aquí le mostramos cómo obtenerlo sin efecto en el ARRAY original

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

Si usa pop (), modificará su matriz

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

Pero puede usar esto para que no tenga efecto en la matriz original:

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 

66
debe hacer slice (-1) .pop (), de lo contrario copiará toda la matriz (realmente solo necesita copiar el último elemento).
kritzikratzi

pop()Entonces no hay necesidad de eso : solo hazloarr.slice(-1)[0]
Christophe Marois

56

La forma más limpia de ES6 (IMO) sería:

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

Esto evita la mutación foo, como lo .pop()habría hecho, si no utilizáramos el operador de propagación.
Dicho esto, también me gusta la foo.slice(-1)[0]solución.


1
También puede usar la desestructuración de la matriz para hacerlo más ES6;) stackoverflow.com/a/46485581/31671
alex

36
Tenga en cuenta que esta solución realiza una copia de toda la matriz.
Brendan Annable

44
Es tan ilegible como .slice(-1)[0]pero es más lento. También podría usarlo.slice
fregante

12
Copiar toda la matriz solo para una sintaxis "limpia" me parece una tontería. Ni siquiera se ve tan bien
Jemar Jones

43

Prefiero usar array.pop()que los índices.

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

de esta manera siempre obtienes el elemento anterior a index.html (siempre que tu matriz tenga index.html aislado como un elemento). Nota: Sin embargo, perderá los últimos elementos de la matriz.


38

Creo que si solo quieres obtener el elemento sin eliminar, es más simple usar esto:

arr.slice(-1)[0]

Nota: Si la matriz está vacía (por ejemplo []), esto regresará undefined.

por cierto ... no verifiqué el rendimiento, pero creo que es más simple y limpio de escribir


Tenga en cuenta que a) esto no devuelve el último valor, sino una matriz con el último elemento ( arr.slice(-1)[0] === arr[arr.length - 1]), yb) es lento porque se copia arren una nueva matriz (consulte stackoverflow.com/a/51763533/2733244 para medir el rendimiento).
wortwart

33

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

Array.prototype.slice con -1 se puede usar para crear una nueva matriz que contenga solo el último elemento de la matriz original, luego puede usar la asignación de desestructuración para crear una variable usando el primer elemento de esa nueva matriz.

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

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


30

Se puede obtener el último elemento de una matriz utilizando el método de división con valores negativos.

Puedes leer más sobre esto aquí en la parte inferior.

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

El uso de pop () cambiará su matriz, lo que no siempre es una buena idea.


1
Sin embargo, Slice devuelve una matriz, así que úsala arr.slice(-1)[0], como esta respuesta .
Cees Timmerman

44
Si el rendimiento es un problema, sepa que este método es mucho más lento que array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres

29

Puedes usar este patrón ...

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

Si bien se lee bastante bien, tenga en cuenta que crea una nueva matriz, por lo que es menos eficiente que otras soluciones, pero casi nunca será el cuello de botella de rendimiento de su aplicación.


25

Esta pregunta ha existido desde hace mucho tiempo, por lo que me sorprende que nadie haya mencionado volver a poner el último elemento después de un pop().

arr.pop()es exactamente tan eficiente como arr[arr.length-1], y ambos tienen la misma velocidad que arr.push().

Por lo tanto, puede salirse con la suya:

--- EDITADO [comprobar que thePopno es undefinedantes de presionar] ---

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

--- EDICIÓN FINAL ---

Que se puede reducir a esto (misma velocidad [EDITAR: ¡pero inseguro!]):

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

Esto es dos veces más lento que arr[arr.length-1], pero no tiene que andar con un índice. Eso vale oro en cualquier día.

De las soluciones que he probado, y en múltiplos de la Unidad de Tiempo de Ejecución (ETU) de arr[arr.length-1]:

[Método] .............. [ETUs 5 elems] ... [ETU 1 millón de elems]

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

Las últimas tres opciones, ESPECIALMENTE [...arr].pop(), empeoran MUCHO a medida que aumenta el tamaño de la matriz. En una máquina sin las limitaciones de memoria de mi máquina, [...arr].pop()probablemente mantiene algo así como su relación 120: 1. Aún así, a nadie le gusta un recurso cerdo.


3
Si la matriz inicial puede estar vacía, este enfoque resultará incorrectamente y []se convertirá en [undefined]. undefinedmyPop !== undefined && arr.push(myPop)
Debe

23

Si uno quiere obtener el último elemento de una vez, puede usar Array#splice():

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

Aquí, no hay necesidad de almacenar los elementos divididos en una matriz, y luego llegar al último elemento. Si obtener el último elemento es el único objetivo, se debe usar.

Nota: Esto cambia la matriz original al eliminar su último elemento. Piense splice(-1,1)como una pop()función que muestra el último elemento.


55
¿No devuelve esto el último elemento en una matriz, en lugar del último elemento en sí?

2
@tozazaburo, ¿no es lo mismo?
Aram Kocharyan

55
Esto modifica la matriz. podría usar la división (-1) en lugar del empalme (-1) para dejar intacta la matriz original. @AramKocharyan no, no, comparar ["hi"]vs "hi".
kritzikratzi

20

Para aquellos que no temen sobrecargar el prototipo de Array (y con el enmascaramiento de enumeración no deberían estarlo):

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


18

Generalmente uso subrayado , con él puedes hacer

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

Para mí eso es más semántico que loc_array.slice(-1)[0]


18

Aquí hay más arte Javascript si viniste a buscarlo

En el espíritu de otra respuesta que usó reduceRight(), pero más corta:

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

Se basa en el hecho de que, en caso de que no proporcione un valor inicial, el último elemento se selecciona como el inicial (consulte los documentos aquí ). Como la devolución de llamada sigue devolviendo el valor inicial, el último elemento será el que se devuelve al final.

Tenga en cuenta que esto debería considerarse arte Javascript y de ninguna manera recomendaría hacerlo, principalmente porque se ejecuta en tiempo O (n), pero también porque perjudica la legibilidad.

Y ahora por la respuesta seria

La mejor manera que veo (considerando que lo quieres más conciso que array[array.length - 1]) es esto:

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

Entonces solo use la función:

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

La función es realmente útil en caso de que se trate de una matriz anónima como la [3, 2, 1, 5]utilizada anteriormente, de lo contrario, tendría que instanciarla dos veces, lo que sería ineficiente y feo:

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

Ugh

Por ejemplo, aquí hay una situación en la que tiene una matriz anónima y tendría que definir una variable, pero puede usar last()en su lugar:

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

16

Solo pongo otra opción aquí.

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

Encontré el enfoque anterior más limpio y corto en línea. Por favor, siéntase libre de probar este.

Nota: modificará la matriz original; si no desea modificarla, puede usar slice()

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

Gracias @VinayPai por señalar esto.


Según el comentario de stackoverflow.com/users/510036/qix-monica-was-mistreated en esta publicación stackoverflow.com/questions/9050345/… y las pruebas en jsperf.com/last-array-element2 que es extremadamente lento
Subash

13

Múltiples formas de encontrar el último valor de una matriz en javascript

  • Sin afectar la matriz original

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

  • Modifica la matriz original.

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

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

  • Mediante la creación de un método auxiliar propio

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

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

console.log(arr.last);


Si su primer ejemplo indica que "Sin afectar la matriz original" y haciendo lo sugerido: console.log(arr.reverse()[0]) - felicidades, acaba de modificar la matriz original.
Roko C. Buljan

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

Estas son las mejores opciones desde el punto de vista del rendimiento (~ 1000 veces más rápido que arr.slice (-1)).


10

Personalmente, votaría por kuporific / kritzikratzi. El método de matriz [array.length-1] se vuelve muy feo si está trabajando con matrices anidadas.

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

Para evitar eliminar el último elemento de la matriz de origen, puede usar

Array.from(myArray).pop()

Principalmente compatible con todos los navegadores (ES6)


1
Buena suerte con grandes matrices de 100.000 elementos o más.
Soldeplata Saketos

9

Puede agregar una last()función al Arrayprototipo.

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

9

Hagas lo que hagas, ¡no lo uses reverse()!

Algunas respuestas mencionan reversepero no mencionan el hecho de que reversemodifica la matriz original y no devuelve (como en otros lenguajes o marcos) una copia.

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

¡Este puede ser el peor tipo de código para depurar!


44
Si desea una copia invertida de su matriz, puede usar el operador de propagación ahora. por ejemplo[...animals].reverse()
Josh R el

simplemente puede copiar la matriz antes de usar el reverso[1,3,4,5,"last"].slice().reverse()[0]
Madeo

9

La desestructuración de objetos ES6 es otro camino a seguir.

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

Extrae la propiedad de longitud de la matriz mediante la desestructuración de objetos. Puede crear otra clave dinámica utilizando la clave ya extraída por [longitud-1] y asignarla al último , todo en una línea.


un poco complicado pero inteligente.
Adrien Castagliola

Gracias, ¿puedes explicar qué hace exactamente?
Tarun Nagpal

8

Puede agregar un nuevo captador de propiedades al prototipo deArray modo que sea accesible a través de todas las instancias de Array.

Los captadores le permiten acceder al valor de retorno de una función como si fuera el valor de una propiedad. El valor de retorno de la función, por supuesto, es el último valor de la matriz ( this[this.length - 1]).

Finalmente lo envuelve en una condición que verifica si la lastpropiedad todavía está undefined(no definida por otro script que pueda depender de ella).

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'

No funciona en IE ≤ 8.


Array.prototype.lastes siempre undefined? El if no funciona en Chrome 36
bryc

7

EDITADO:

Recientemente se me ocurrió una solución más que ahora creo que es la mejor para mis necesidades:

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

Con la definición anterior en efecto, ahora puedo decir:

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

El nombre "w" significa "envoltorio". Puede ver cómo podría agregar fácilmente más métodos además de 'last ()' a este contenedor.

Digo "lo mejor para mis necesidades", porque esto me permite agregar fácilmente otros "métodos auxiliares" a cualquier tipo de JavaScript incorporado. Lo que viene a la mente son el auto () y el cdr () de Lisp, por ejemplo.


¿Por qué usar una envoltura? Si tiene que llamar a una wfunción, simplemente haga que la función devuelva el último elemento.
fregante

w([1,2,3]).lengthes indefinido. w([1,2,3])[1]es indefinido. No me parece una envoltura. Y hay un error de sintaxis. Tienes un ';' extra. Consulte stackoverflow.com/a/49725374/458321 para saber cómo escribir un contenedor de clase (clase SutString) y usar la reflexión para llenar ese contenedor. Aunque, en mi humilde opinión, los envoltorios son excesivos. Es mejor usar encapsulación, como casi lo tienes. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Además, w es demasiado genérico. La llamada es ArrayW o algo así.
TamusJRoyce

6

Creo que la forma más fácil y súper ineficiente es:

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

43
Esta solución toma O (n) más memoria y toma O (n) tiempo. Realmente no es la solución ideal.
hlin117
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.