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.

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.


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.


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


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];
}

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 

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.


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.


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


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


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.


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.


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.


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.


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


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]


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("."));

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é.



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


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


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]


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)


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];
};

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!


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.


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.


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.


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".

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.