Récupère le dernier élément d'un tableau

1142

Voici mon code JavaScript jusqu'à présent:

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

Actuellement, il prend l'avant-dernier élément du tableau à partir de l'URL. Cependant, je veux vérifier que le dernier élément du tableau soit"index.html" et si c'est le cas, saisir le troisième au dernier élément à la place.

balexandre
la source

Réponses:

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

Dans le cas où votre serveur sert le même dossier pour « index.html » et « index.html » , vous pouvez également utiliser: .toLowerCase().

Cependant, vous voudrez peut-être envisager de faire cela côté serveur si possible: il sera plus propre et fonctionnera pour les personnes sans JS.

Aaron Harun
la source
si vous avez juste besoin du dernier article, vous pouvez vous Array.pop ()
Badri Derakhshan Il y a
1052

Je ne sais pas s'il y a un inconvénient, mais cela semble assez concis:

arr.slice(-1)[0] 

ou

arr.slice(-1).pop()

Les deux reviendront undefinedsi le tableau est vide.

kritzikratzi
la source
32
utiliser la déstructuration est bien aussi:const [lastItem] = arr.slice(-1)
diachedelic
@diachedelic c'est la manière la plus simple! Impressionnant!
Trufa
2
.pop()supprime le dernier élément qui modifie le tableau d'origine. Ce n'est pas la même chose que de simplement récupérer cette valeur.
Badrush
4
@Badrush slice () crée un nouveau tableau avec une copie d'un seul élément, et pop ne modifie que cette copie. le tableau d'origine reste
intact
Mais vous devez éviter de créer de nouveaux tableaux à moins que ce code ne soit pas appelé souvent. Sinon, cela mettra une pression supplémentaire sur la collecte des ordures et / ou fera en sorte que le navigateur utilise plus de mémoire.
mvmn
259

Utilisez Array.pop :

var lastItem = anArray.pop();

Important : cela renvoie le dernier élément et le supprime du tableau

mohawke
la source
165

Une version plus courte de ce que @chaiguy a publié:

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

Lecture des rendements de l'indice -1 undefined déjà.

ÉDITER:

De nos jours, la préférence semble être d'utiliser des modules et d'éviter de toucher au prototype ou d'utiliser un espace de noms global.

export function last(array) {
    return array[array.length - 1];
}
Aram Kocharyan
la source
8
Si ce n'est pas évident comment cela doit être effectivement utilisé, voici un exemple: var lastItem = [3,2,1,5].last();. La valeur de lastItemest 5.
user128216
7
Cette réponse est correcte et aussi assez propre MAIS (!!!) Une règle de base en utilisant Javascript est celle-ci Do NOT modify objects you Do NOT own. C'est dangereux pour de nombreuses raisons, telles que 1. D'autres développeurs travaillant dans votre équipe pourraient être confus car cette méthode n'est pas standard 2. avec toute mise à jour dans les bibliothèques ou même en utilisant une version ECMAScript inférieure ou supérieure, elle pourrait facilement être PERDUE!
Farzad YZ
1
Pour quiconque se pose la question, cela brise Array.forEach (). Je suis toujours d'accord que modifier des prototypes n'est pas la pire chose, mais celui-ci est mauvais.
Seph Reed du
1
Imo il n'y a pas un gros problème avec la modification Array.prototype, mais vous devriez utiliser Object.assign(Array.prototype, 'last', { value: function () { … } });. Sinon, la propriété sera énumérable.
黄 雨伞
70

Voici comment l'obtenir sans effet sur l'ARRAY d'origine

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

Si vous utilisez pop (), cela modifiera votre tableau

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

Mais vous pouvez utiliser ceci afin qu'il n'ait aucun effet sur le tableau d'origine:

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
la source
6
vous devez faire slice (-1) .pop (), sinon vous copiez le tableau entier (vous n'avez vraiment besoin que de copier le dernier élément).
kritzikratzi
Pas besoin de ça pop()alors: fais-learr.slice(-1)[0]
Christophe Marois
56

La voie ES6 la plus "propre" (IMO) serait:

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

Cela évite de muter foo, comme cela .pop()aurait été le cas, si nous n'avions pas utilisé l'opérateur d'étalement.
Cela dit, j'aime aussi la foo.slice(-1)[0]solution.

ddd
la source
1
Vous pouvez également utiliser la déstructuration de la baie pour la rendre plus ES6;) stackoverflow.com/a/46485581/31671
alex
36
Notez que cette solution effectue une copie de l'ensemble de la baie.
Brendan Annable
4
C'est tout aussi illisible .slice(-1)[0]mais plus lent. Peut aussi bien être utilisé.slice
fregante
12
Copier tout le tableau juste pour une syntaxe "propre" me semble idiot. Il n'a même pas l'air si joli
Jemar Jones
43

Je préfère utiliser des array.pop()index.

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

de cette façon, vous obtenez toujours l'élément précédent à index.html (à condition que votre tableau ait index.html isolé comme un élément). Remarque: vous perdrez cependant les derniers éléments du tableau.

Pablo Mescher
la source
38

Je pense que si vous voulez seulement récupérer l'élément sans le supprimer, il est plus simple d'utiliser ceci:

arr.slice(-1)[0]

Remarque: Si le tableau est vide (par exemple []), cela reviendra undefined.

au fait ... je n'ai pas vérifié les performances, mais je pense que c'est plus simple et propre à écrire

terribleWeb
la source
Notez que a) cela ne renvoie pas la dernière valeur mais un tableau avec le dernier élément ( arr.slice(-1)[0] === arr[arr.length - 1]), et b) il est lent car il copie arrdans un nouveau tableau (voir stackoverflow.com/a/51763533/2733244 pour la mesure des performances).
wortwart
33

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

Array.prototype.slice avec -1 peut être utilisé pour créer un nouveau tableau contenant uniquement le dernier élément du tableau d'origine, vous pouvez ensuite utiliser déstructuration pour créer une variable en utilisant le premier élément de ce nouveau tableau.

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
la source
30

L'obtention du dernier élément d'un tableau peut être obtenue en utilisant la tranche méthode de avec des valeurs négatives.

Vous pouvez en savoir plus ici en bas.

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

L'utilisation de pop () changera votre tableau, ce qui n'est pas toujours une bonne idée.

Mohoch
la source
1
Cependant, Slice renvoie un tableau, alors utilisez-le arr.slice(-1)[0], comme cette réponse .
Cees Timmerman
4
Si les performances sont un problème, sachez que cette méthode est beaucoup plus lente que array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres
29

Vous pouvez utiliser ce modèle ...

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

Bien qu'il se lise plutôt bien, gardez à l'esprit qu'il crée un nouveau tableau, il est donc moins efficace que d'autres solutions, mais ce ne sera presque jamais le goulot d'étranglement des performances de votre application.

alex
la source
25

Cette question existe depuis longtemps, donc je suis surpris que personne n'ait mentionné simplement remettre le dernier élément après a pop().

arr.pop()est exactement aussi efficace que arr[arr.length-1], et les deux ont la même vitesse que arr.push().

Par conséquent, vous pouvez vous en sortir avec:

--- ÉDITÉ [vérifier que ce thePopn'est pas undefinedavant de pousser] ---

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

--- FIN DE LA MODIFICATION ---

Ce qui peut être réduit à cela (même vitesse [EDIT: mais dangereux!]):

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

C'est deux fois plus lent que cela arr[arr.length-1], mais vous n'avez pas besoin de farfouiller avec un index. Cela vaut de l'or n'importe quel jour.

Parmi les solutions que j'ai essayées, et en multiples de l'Execution Time Unit (ETU) de arr[arr.length-1] :

[Méthode] .............. [ETUs 5 elems] ... [ETU 1 million 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 :)

Les trois dernières options, EN PARTICULIER [...arr].pop(), deviennent TRÈS bien pires à mesure que la taille du tableau augmente. Sur une machine sans les limites de mémoire de ma machine, [...arr].pop()maintient probablement quelque chose comme son rapport 120: 1. Pourtant, personne n'aime un porc de ressources.

Paul Parker
la source
3
Si le tableau initial peut être vide, cette approche entraînera un résultat incorrect et []sera transformée en [undefined]. Vous devez protéger la poussée vers l'arrière avec une undefinedvérification explicite , quelque chose commemyPop !== undefined && arr.push(myPop)
dhilt
23

Si l'on veut obtenir le dernier élément d'un coup, il peut utiliser Array#splice():

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

Ici, il n'est pas nécessaire de stocker les éléments divisés dans un tableau, puis d'accéder au dernier élément. Si obtenir le dernier élément est le seul objectif, celui-ci doit être utilisé.

Remarque: cela modifie le tableau d'origine en supprimant son dernier élément. Considérez splice(-1,1)comme une pop()fonction qui fait apparaître le dernier élément.

user1144616
la source
5
Cela ne renvoie-t-il pas le dernier élément d'un tableau, au lieu du dernier élément lui-même?
2
@tozazaburo n'est-ce pas la même chose?
Aram Kocharyan
5
cela modifie le tableau. vous pouvez utiliser slice (-1) au lieu de splice (-1) pour laisser le tableau d'origine intact. @AramKocharyan Nô son pas, comparer ["hi"]vs "hi".
kritzikratzi
20

Pour ceux qui n'ont pas peur de surcharger le prototype Array (et avec le masquage d'énumération, vous ne devriez pas l'être):

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

jQuery résout parfaitement:

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

J'utilise généralement des traits de soulignement , avec cela vous pouvez simplement faire

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

Pour moi, c'est plus sémantique que loc_array.slice(-1)[0]

niels
la source
18

Voici plus d'art Javascript si vous êtes venu le chercher

Dans l'esprit d'une autre réponse utilisée reduceRight(), mais plus courte:

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

Il repose sur le fait que, si vous ne fournissez pas de valeur initiale, le tout dernier élément est sélectionné comme élément initial (consultez la documentation ici ). Puisque le rappel continue de renvoyer la valeur initiale, le dernier élément sera celui renvoyé à la fin.

Attention, cela devrait être considéré comme de l' art Javascript et ce n'est en aucun cas la façon dont je recommanderais de le faire, principalement parce qu'il fonctionne en temps O (n), mais aussi parce que cela nuit à la lisibilité.

Et maintenant pour la réponse sérieuse

La meilleure façon que je vois (étant donné que vous le voulez plus concis que array[array.length - 1]) est la suivante:

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

Ensuite, utilisez simplement la fonction:

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

La fonction est en fait utile dans le cas où vous avez affaire à un tableau anonyme comme [3, 2, 1, 5]utilisé ci-dessus, sinon vous devrez l'instancier deux fois, ce qui serait inefficace et laid:

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

Pouah.

Par exemple, voici une situation où vous avez un tableau anonyme et vous devez définir une variable, mais vous pouvez utiliser à la last()place:

last("1.2.3".split("."));
Lucio Paiva
la source
16

Je mets juste une autre option ici.

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

J'ai trouvé l'approche ci-dessus plus propre et plus courte. S'il vous plaît, n'hésitez pas à essayer celui-ci.

Remarque: Il modifiera le tableau d'origine, si vous ne voulez pas le modifier, vous pouvez utiliser slice()

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

Merci @VinayPai de l' avoir signalé.

sidgujrathi
la source
Selon le commentaire de stackoverflow.com/users/510036/qix-monica-was-mistreated sur ce post stackoverflow.com/questions/9050345/… et les tests sur jsperf.com/last-array-element2 qui sont extrêmement lents
Subash
13

Plusieurs façons de trouver la dernière valeur d'un tableau en javascript

  • Sans affecter la baie d'origine

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

  • Modifie le tableau d'origine

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

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

  • En créant sa propre méthode d'assistance

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

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

console.log(arr.last);

Vahid Akhtar
la source
Si votre premier exemple où vous dites "sans affecter le tableau d'origine" et en faisant comme suggéré: console.log(arr.reverse()[0]) - félicitations, vous venez de modifier le tableau d'origine.
Roko C. Buljan
12
const lastElement = myArray[myArray.length - 1];

Il s'agit des meilleures options du point de vue des performances (~ 1000 fois plus rapide que arr.slice (-1)).

Alexander Burakevych
la source
10

Personnellement, je voterais en réponse par kuporific / kritzikratzi. La méthode array [array.length-1] devient très moche si vous travaillez avec des tableaux imbriqués.

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
la source
10

Pour éviter de supprimer le dernier élément du tableau d'origine, vous pouvez utiliser

Array.from(myArray).pop()

Principalement pris en charge par tous les navigateurs (ES6)

Alexandr Malinin
la source
1
bonne chance avec de grands tableaux de 100 000 éléments ou plus.
Soldeplata Saketos
9

Vous pouvez ajouter une last()fonction au Arrayprototype.

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

Quoi que vous fassiez ne pas simplement utiliser reverse()!!!

Quelques réponses mentionnent reversemais ne mentionnent pas le fait que reversele tableau d'origine est modifié et ne renvoie pas (comme dans d'autres langages ou frameworks) une copie.

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

Cela peut être le pire type de code à déboguer!

Simon_Weaver
la source
4
Si vous voulez une copie inversée de votre tableau, vous pouvez utiliser maintenant l'opérateur d'étalement. par exemple[...animals].reverse()
Josh R
vous pouvez simplement copier le tableau avant d'utiliser le reverse[1,3,4,5,"last"].slice().reverse()[0]
Madeo
9

La déstructuration d'objets ES6 est une autre solution.

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

Vous extrayez la propriété length d'Array à l'aide de la déstructuration d'objets. Vous créez une autre clé dynamique en utilisant la clé déjà extraite par [longueur-1] et l'affectez à la dernière , le tout sur une seule ligne.

gautamits
la source
un peu délicat mais intelligent.
Adrien Castagliola
Merci, pouvez-vous expliquer ce que cela fait exactement?
Tarun Nagpal
8

Vous pouvez ajouter un nouvel getter de propriété au prototype deArray afin qu'il soit accessible via toutes les instances de Array.

Les accesseurs vous permettent d'accéder à la valeur de retour d'une fonction comme s'il s'agissait de la valeur d'une propriété. La valeur de retour de la fonction est bien sûr la dernière valeur du tableau ( this[this.length - 1]).

Enfin, vous l' lastencapsulez dans une condition qui vérifie si la propriété est toujours undefined(non définie par un autre script qui pourrait s'y fier).

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'

Ne fonctionne pas dans IE ≤ 8.

Matmarbon
la source
Array.prototype.lastest toujours undefined? L'if ne fonctionne pas sous Chrome 36
bryc
7

ÉDITÉ:

Récemment, j'ai trouvé une autre solution que je pense maintenant être la meilleure pour mes besoins:

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

Avec la définition ci-dessus en vigueur, je peux maintenant dire:

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

Le nom "w" signifie "wrapper". Vous pouvez voir comment vous pouvez facilement ajouter plus de méthodes en plus de 'last ()' à ce wrapper.

Je dis «le mieux pour mes besoins», car cela me permet d'ajouter facilement d'autres «méthodes d'assistance» à n'importe quel type intégré JavaScript. Ce qui me vient à l'esprit, ce sont les voitures () et cdr () de Lisp par exemple.

Panu Logic
la source
Pourquoi utiliser un wrapper? Si vous devez appeler une wfonction, faites-la renvoyer le dernier élément.
fregante
w([1,2,3]).lengthn'est pas défini. w([1,2,3])[1]n'est pas défini. Cela ne me semble pas comme un wrapper. Et il y a une erreur de syntaxe. Vous avez un extra ';'. Voir stackoverflow.com/a/49725374/458321 pour savoir comment écrire un wrapper de classe (classe SutString) et utiliser la réflexion pour remplir ce wrapper. Cependant, à mon humble avis, les emballages sont exagérés. Mieux vaut utiliser l'encapsulation, comme vous l'avez presque fait. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. De plus, w est bien trop générique. L'appel est ArrayW ou quelque chose.
TamusJRoyce
6

Je pense que le moyen le plus simple et le plus inefficace est:

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
la source
43
Cette solution prend O (n) plus de mémoire et prend du temps O (n). Ce n'est vraiment pas la solution idéale.
hlin117