Obter o último item em uma matriz

Aqui está o meu código JavaScript até agora:

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

Atualmente, leva o segundo ao último item da matriz a partir do URL. No entanto, eu quero fazer uma verificação para o último item na matriz para ser “index.html” e em caso afirmativo, pegue o terceiro ao último item em vez disso.

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

No caso de o servidor servir o mesmo arquivo para “index.html” e “inDEX.htML”, você também poderá usar: .toLowerCase() .

Porém, você pode querer considerar fazer este lado do servidor se possível: ele será mais limpo e funcionará para pessoas sem JS.

Não tenho certeza se há uma desvantagem, mas isso parece bastante conciso:

 arr.slice(-1)[0] 

ou

 arr.slice(-1).pop() 

Ambos retornarão undefined se a matriz estiver vazia.

Use Array.pop :

 var lastItem = anArray.pop(); 

Importante : Isso retorna o último elemento e o remove da matriz

Uma versão mais curta do que @chaiguy postou:

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

A leitura do índice -1 retorna undefined .

Duas opções são:

 var last = arr[arr.length - 1] 

ou

 var last = arr.slice(-1)[0] 

O primeiro é mais rápido, mas o segundo parece melhor

http://jsperf.com/slice-vs-length-1-arr

Veja como obtê-lo sem efeito no ARRAY original

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

Se você usar pop (), ele modificará sua matriz

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

Mas você pode usar isso para que não tenha efeito no array 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 

Eu prefiro usar array.pop() que índices.

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

Dessa forma, você sempre obtém o elemento anterior a index.html (desde que seu array tenha index.html isolado como um item). Nota: Você vai perder os últimos elementos da matriz, no entanto.

A maneira mais “limpa” do ES6 (IMO) seria:

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

Isso evita a mutação como pop se não tivéssemos usado o operador de propagação. Dito isso, eu também gosto da foo.slice(-1)[0] .

Obter o último item de uma matriz pode ser obtido usando o método de fatia com valores negativos.

Você pode ler mais sobre isso aqui na parte inferior.

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

O uso de pop () mudará sua matriz, o que nem sempre é uma boa ideia.

Se alguém quiser obter o último elemento de uma só vez, ele / ela pode usar Array#splice() :

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

Aqui, não há necessidade de armazenar os elementos de divisão em uma matriz e, em seguida, chegar ao último elemento. Se a obtenção do último elemento for o único objective, isso deve ser usado.

Nota: Isso altera o array original removendo seu último elemento. Pense em splice(-1,1) como uma function pop() que aparece no último elemento.

O jQuery resolve isso bem:

 > $([1,2,3]).get(-1) 3 > $([]).get(-1) undefined 

Você pode usar esse padrão …

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

Enquanto ele lê muito bem, lembre-se de que ele cria uma nova matriz para que seja menos eficiente do que outras soluções, mas quase nunca será o gargalo de desempenho de sua aplicação.

Para aqueles que não têm medo de sobrecarregar o protótipo do Array (e com o mascaramento de enumeração, você não deveria estar):

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

Eu geralmente uso underscorejs , com isso você pode apenas fazer

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

Para mim, isso é mais semântico que loc_array.slice(-1)[0]

Você pode adicionar uma function last() ao protótipo Array .

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

Pessoalmente, eu iria votar positivamente por kuporific / kritzikratzi. O método array [array.length-1] fica muito feio quando se trabalha com matrizes aninhadas.

 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] 
 const lastElement = myArray[myArray.length - 1]; 

Essas são as melhores opções do ponto de vista do desempenho (~ 1000 vezes mais rápido que arr.slice (-1)).

Você pode adicionar um novo getter de propriedade ao protótipo do Array para que ele seja acessível em todas as instâncias do Array .

Os getters permitem que você acesse o valor de retorno de uma function como se fosse o valor de uma propriedade. O valor de retorno da function, claro, é o último valor da matriz ( this[this.length - 1] ).

Por fim, você o envolve em uma condição que verifica se a last propriedade ainda está undefined (não definida por outro script que possa depender dela).

 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' 

Não funciona no IE ≤ 8.

EDITADO:

Recentemente eu criei mais uma solução que agora acho que é a melhor para minhas necessidades:

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

Com a definição acima em vigor agora posso dizer:

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

O nome “w” significa “invólucro”. Você pode ver como é fácil adicionar mais methods além de ‘last ()’ a este wrapper.

Eu digo “melhor para minhas necessidades”, porque isso me permite adicionar facilmente outros “methods auxiliares” a qualquer tipo de JavaScript embutido. O que vem à mente são o carro () e cdr () do Lisp por exemplo.

Eu acho que a maneira mais fácil e super ineficiente é:

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

Vou sugerir para criar a function auxiliar e reutilizá-lo sempre, você precisará dele. Vamos tornar a function mais geral para obter não apenas o último item, mas também o segundo do último e assim por diante.

 function last(arr, i) { var i = i || 0; return arr[arr.length - (1 + i)]; } 

O uso é simples

 var arr = [1,2,3,4,5]; last(arr); //5 last(arr, 1); //4 last(arr, 9); //undefined 

Agora, vamos resolver o problema original

Agarre segundo a última matriz de formulário de item. Se o último item no loc_array for “index.html”, escolha o terceiro para o último item.

Próxima linha faz o trabalho

 last(loc_array, last(loc_array) === 'index.html' ? 2 : 1); 

Então, você precisará rewrite

 var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-2]))); 

nesse caminho

 var newT = document.createTextNode(unescape(capWords(last(loc_array, last(loc_array) === 'index.html' ? 2 : 1)))); 

ou use uma variável adicional para aumentar a legibilidade

 var nodeName = last(loc_array, last(loc_array) === 'index.html' ? 2 : 1); var newT = document.createTextNode(unescape(capWords(nodeName))); 

Esta questão tem sido em torno de um longo tempo, por isso estou surpreso que ninguém mencionou apenas colocando o último elemento de volta depois de um pop() .

arr.pop() é exatamente tão eficiente quanto arr[arr.length-1] , e ambos são da mesma velocidade que arr.push() .

Portanto, você pode se safar:

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

Que pode ser reduzido para isso (mesma velocidade):

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

Isso é duas vezes mais lento que arr[arr.length-1] , mas você não precisa se arr[arr.length-1] com um índice. Isso vale ouro em qualquer dia.

Das soluções que eu tentei, e em múltiplos da Unidade de Tempo de Execução (ETU) de arr[arr.length-1] :

[Método] ………….. [ETUs 5 elems] … [ETU 1 milhão de elementos]

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

As últimas três opções, ESPECIALLY [...arr].pop() , ficam muito piores quando o tamanho da matriz aumenta. Em uma máquina sem as limitações de memory da minha máquina, [...arr].pop() provavelmente mantém algo como sua proporção de 120: 1. Ainda assim, ninguém gosta de um porco de resources.

Usando lodash _.last (array) Obtém o último elemento da matriz.

 data = [1,2,3] last = _.last(data) console.log(last) 
  

Você pode conseguir esse problema também sem extrair um array do URL

Esta é minha alternativa

 var hasIndex = (document.location.href.search('index.html') === -1) ? doSomething() : doSomethingElse(); 

!Saudações

Usando o operador de espalhamento ES6 / ES2015 (…), você pode fazer o seguinte.

 const data = [1, 2, 3, 4] const [last] = [...data].reverse() console.log(last) 

Eu acho que se você só quer pegar o elemento sem remover, é mais simples usar isso:

 arr.slice(-1) 

pelo caminho … eu não verifiquei o desempenho, mas eu acho que é mais simples e limpo para escrever

Há também um módulo npm, que é adicionado por last ao Array.prototype

 npm install array-prototype-last --save 

uso

 require('array-prototype-last'); [1, 2, 3].last; //=> 3 [].last; //=> undefined 

Outra opção somente do ES6 seria usar Array.find(item, index)=> {...}) seguinte maneira:

 const arr = [1, 2, 3]; const last = arr.find((item, index) => index === arr.length - 1); 

pequeno valor prático, postado para mostrar que o índice também está disponível para sua lógica de filtragem.

Isso vai funcionar?

 if (loc_array.pop() == "index.html"){ var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-3]))); } else{ var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-2]))); } 

Usando reduceRight :

 [3,2,1,5].reduceRight((a,v) => { return a?a:v; });