Получить последний элемент в массиве

Вот мой код JavaScript на данный момент:

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

В настоящее время требуется предпоследний элемент массива из URL-адреса. Однако я хочу проверить, чтобы последний элемент в массиве был "index.html", и если да, то вместо этого возьмитесь с третьего до последнего элемента.


person balexander    schedule 09.07.2010    source источник


Ответы (54)


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

Если ваш сервер обслуживает один и тот же файл для index.html и inDEX.htML, вы также можете использовать: .toLowerCase().

Тем не менее, вы можете подумать о том, чтобы сделать это на стороне сервера, если это возможно: это будет чище и будет работать для людей без JS.

person Aaron Harun    schedule 09.07.2010
comment
если вам нужен только последний элемент, вы можете Array.pop () - person Badri Derakhshan; 07.06.2020
comment
@BadriDerakhshan Это неизбежно приведет к удалению последнего элемента из массива перед его возвратом, поэтому это не вариант, если вы просто хотите проверить последний элемент массива. Вам также придется отодвинуть его обратно, чтобы восстановить массив до прежнего состояния. - person Robidu; 01.11.2020
comment
Вы должны проверить, пуст ли массив. Пустой массив - это допустимый массив. - person suyuti; 30.12.2020
comment
Решение от @BadriDerakhshan полезно в случаях, когда созданный массив является временным. Например, вместо x = string.split('/'); return x[x.length-1] вы можете сделать return x.split('/').pop() - person Harry; 27.05.2021

Не уверен, есть ли здесь недостаток, но это кажется довольно кратким:

arr.slice(-1)[0] 

or

arr.slice(-1).pop()

Оба вернут undefined, если массив пуст.

person kritzikratzi    schedule 23.08.2012
comment
использовать деструктуризацию тоже приятно: const [lastItem] = arr.slice(-1) - person diachedelic; 11.03.2019
comment
.pop() удаляет последний элемент, изменяющий исходный массив. Это не то же самое, что просто получить это значение. - person Badrush; 06.05.2020
comment
@Badrush slice () создает новый массив с копией одного элемента, а pop изменяет только эту копию. исходный массив остается невредимым - person kritzikratzi; 07.05.2020
comment
Но вам следует избегать создания новых массивов, если этот код не вызывается часто. В противном случае это создаст дополнительную нагрузку на сборку мусора и / или заставит браузер использовать больше памяти. - person mvmn; 01.06.2020
comment
@mvmn Давным-давно я проводил тест, пропускная способность составляла около одного или двух миллионов вызовов в секунду на одном потоке 2,4 ГГц. поэтому, если у вас нет проблем, которые вы все равно не должны решать в JS, это не будет заметно (замедление iirc по сравнению с arr [arr.length-1] было 50-100x) - person kritzikratzi; 02.06.2020
comment
этот метод очень медленный - person Govan; 22.06.2020
comment
@Govan, пожалуйста, посмотрите мой комментарий. вы можете вызывать это непомерное количество раз в секунду. если вам нужно больше или длина массива легко доступна, используйте обычный доступ к массиву для максимальной производительности arr[arr.length-1] - person kritzikratzi; 22.06.2020

Используйте Array.pop:

var lastItem = anArray.pop();

Важно: возвращает последний элемент и удаляет его из массива.

person mohawke    schedule 14.06.2012
comment
особенно хорош для чего-то вроде: filename.split('.').pop() - person armin.miedl; 12.03.2021

Более короткая версия того, что опубликовал @chaiguy:

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

Чтение индекса -1 уже возвращает undefined.

РЕДАКТИРОВАТЬ:

В наши дни, похоже, предпочтение отдается использованию модулей и избеганию прикосновения к прототипу или использованию глобального пространства имен.

export function last(array) {
    return array[array.length - 1];
}
person Aram Kocharyan    schedule 01.10.2012
comment
Если не совсем понятно, как это должно использоваться на самом деле, вот пример: var lastItem = [3,2,1,5].last();. Значение lastItem равно 5. - person user5670895; 05.12.2015
comment
Этот ответ правильный и довольно чистый, НО (!!!) Основное правило использования Javascript - Do NOT modify objects you Do NOT own. Это опасно по многим причинам, например: 1. Другие разработчики, работающие в вашей команде, могут запутаться, поскольку этот метод не является стандартным. 2. с любым обновлением в библиотеках или даже с использованием более низкой или более высокой версии ECMAScript он может легко потеряться! - person Farzad Yousefzadeh; 13.10.2016
comment
Для всех, кому интересно, это нарушает работу Array.forEach (). Я все еще согласен с тем, что модификация прототипов - не самое худшее, но это плохо. - person Seph Reed; 25.10.2017
comment
Imo, нет такой большой проблемы с изменением Array.prototype, но вы должны использовать Object.assign(Array.prototype, 'last', { value: function () { … } });. В противном случае свойство будет перечислимым. - person 黄雨伞; 06.09.2018
comment
@FarzadYousefzadeh Интересная статья, в которой рассказывается, когда и как изменять собственный прототип JS. - person Breaking not so bad; 07.05.2021
comment
@Breakingnotsobad Конечно, полифиллинг одобрен, но имейте в виду, что это делается только для стандартных методов или скоро станет стандартом в этом отношении. last в данном случае не является стандартом. - person Farzad Yousefzadeh; 09.05.2021
comment
Если вы собираетесь расширить встроенные прототипы или заполнить свойство (например, monkey-patch), сделайте это правильно: для прямой совместимости проверьте, существует ли свойство сначала , затем сделайте свойство неперечислимым, чтобы не загрязнять собственные ключи построенных объектов. В качестве методов используйте актуальные методы < / а>. Моя рекомендация: как можно точнее следуйте этим примерам, которые демонстрируют, как добавить метод, который ведет себя как другие встроенные методы. - person Sebastian Simon; 09.06.2021
comment
Обратите внимание, что советуем не изменять исходные прототипы, потому что, если бы все это делали, повсюду были бы конфликты. Однако на самом деле есть только одно, что может сделать Array.prototype.last(): независимо от реализации, он вернет последний элемент, не удаляя его (потому что .pop() уже существует для этого), поэтому в этом случае почти наверняка все в порядке, даже если кто-то другой также реализует ту же функцию. Они перезапишут друг друга и продолжат делать то же самое. - person Mike 'Pomax' Kamermans; 25.06.2021

Два варианта:

var last = arr[arr.length - 1]

or

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

Первый быстрее, но второй выглядит лучше

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

person Josh Click    schedule 07.01.2014
comment
Спасибо за ссылку jsperf. Второй вариант - нонсенс с точки зрения производительности. - person Leos Literak; 05.07.2020
comment
Первый вариант также очень очевидно, что он делает. Второй не так много - person isset; 10.08.2020

Вот как это сделать, не влияя на исходный ARRAY

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

Если вы используете pop (), он изменит ваш массив.

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

Но вы можете использовать это, чтобы оно не влияло на исходный массив:

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 
person ucefkh    schedule 03.09.2014
comment
вы должны сделать slice (-1) .pop (), иначе вы скопируете весь массив (вам действительно нужно скопировать только последний элемент). - person kritzikratzi; 30.05.2015
comment
Тогда не нужно pop(): просто сделайте arr.slice(-1)[0] - person Christophe Marois; 12.04.2017

Представление

Сегодня 2020.05.16 я тестирую выбранные решения на Chrome v81.0, Safari v13.1 и Firefox v76.0 на MacOs High Sierra v10.13.6

Выводы

  • arr[arr.length-1] (D) рекомендуется как самое быстрое кросс-браузерное решение.
  • изменяемое решение arr.pop() (A) и неизменное _.last(arr) (L) быстро
  • решения I, J медленные для длинных строк
  • решения H, K (jQuery) самые медленные во всех браузерах

введите описание изображения здесь

Подробности

Я тестирую два случая на предмет решений:

  • изменчивый: A, B, C,

  • неизменяемый: D, E, F, G, H, I, J (мой),

  • неизменяемый из внешних библиотек: K, L, M,

на два случая

  • короткая строка - 10 символов - вы можете запустить тест ЗДЕСЬ
  • длинная строка - 1 млн символов - вы можете запустить тест ЗДЕСЬ

function A(arr) {
  return arr.pop();
}

function B(arr) {  
  return arr.splice(-1,1);
}

function C(arr) {  
  return arr.reverse()[0]
}

function D(arr) {
  return arr[arr.length - 1];
}

function E(arr) {
  return arr.slice(-1)[0] ;
}

function F(arr) {
  let [last] = arr.slice(-1);
  return last;
}

function G(arr) {
  return arr.slice(-1).pop();
}

function H(arr) {
  return [...arr].pop();
}

function I(arr) {  
  return arr.reduceRight(a => a);
}

function J(arr) {  
  return arr.find((e,i,a)=> a.length==i+1);
}

function K(arr) {  
  return $(arr).get(-1);
}

function L(arr) {  
  return _.last(arr);
}

function M(arr) {  
  return _.nth(arr, -1);
}






// ----------
// TEST
// ----------

let loc_array=["domain","a","b","c","d","e","f","g","h","file"];

log = (f)=> console.log(`${f.name}: ${f([...loc_array])}`);

[A,B,C,D,E,F,G,H,I,J,K,L,M].forEach(f=> log(f));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js" integrity="sha256-VeNaFBVDhoX3H+gJ37DpT/nTuZTdjYro9yBruHjVmoQ=" crossorigin="anonymous"></script>

Пример результатов для Chrome для короткой строки

введите описание изображения здесь

person Kamil Kiełczewski    schedule 16.05.2020

Самый "чистый" способ ES6 (IMO) будет:

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

Это позволяет избежать мутации foo, как это было бы в .pop(), если бы мы не использовали оператор распространения.
Тем не менее, мне также нравится решение foo.slice(-1)[0].

person ddd    schedule 16.06.2017
comment
Вы также можете использовать деструктуризацию массива, чтобы сделать его больше ES6;) stackoverflow.com/a/46485581/31671 - person alex; 04.10.2017
comment
Обратите внимание, что это решение выполняет копию всего массива. - person Brendan Annable; 03.07.2018
comment
Он так же нечитабелен, как .slice(-1)[0], но медленнее. Можно также использовать .slice - person fregante; 19.09.2018
comment
Мне кажется глупым копирование всего массива только для чистого синтаксиса. Это даже не выглядит так красиво - person Jemar Jones; 13.12.2018

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

Array.prototype.slice с - 1 можно использовать для создания нового массива, содержащего только последний элемент исходного массива, затем вы можете использовать Destructuring Assignment для создания переменной с использованием первого элемента этого нового массива.

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

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

person Jamie Mason    schedule 29.05.2019
comment
.slice(-1) ответ уже давался несколько раз, начиная с в 2012 году, и его последствия подробно обсуждались (в отличие от здесь). Пожалуйста, не давайте повторяющихся ответов только для того, чтобы получить несколько голосов. - person Dan Dascalescu; 10.06.2020
comment
Мне больше всего нравится этот ответ. В других ответах .slice (-1) я видел использование [0], а не деструктурирование. Комментарий @diachedelic предполагает такую ​​деструктуризацию, но, на мой взгляд, он заслуживает того, чтобы быть ответом, а не комментарием. Также хорошие примеры и ссылки. - person Marcus; 29.10.2020

Я лучше буду использовать array.pop(), чем индексы.

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

таким образом вы всегда получаете элемент, предшествующий index.html (при условии, что ваш массив имеет изолированный index.html как один элемент). Примечание. Однако вы потеряете последние элементы массива.

person Pablo Mescher    schedule 24.02.2012

Вы можете использовать этот шаблон ...

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

Хотя он довольно хорошо читается, имейте в виду, что он создает новый массив, поэтому он менее эффективен, чем другие решения, но почти никогда не будет узким местом производительности вашего приложения.

person alex    schedule 29.09.2017

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

Это лучший вариант с точки зрения производительности (~ в 1000 раз быстрее, чем arr.slice(-1)).

person Alexander Burakevych    schedule 18.06.2014
comment
Как это добавить что-нибудь к верхнему ответу? - person Dan Dascalescu; 10.06.2020

Получить последний элемент массива можно с помощью метода slice с отрицательными значениями.

Вы можете прочитать об этом здесь внизу.

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

Использование pop () изменит ваш массив, что не всегда является хорошей идеей.

person Mohoch    schedule 12.02.2013
comment
Slice возвращает массив, поэтому используйте arr.slice(-1)[0], например этот ответ. - person Cees Timmerman; 21.05.2013
comment
Если производительность является проблемой, знайте, что этот метод намного медленнее, чем array[array.length - 1] jsperf. ru / get-last-item-from-array / 13 - person Bruno Peres; 08.03.2017

Если кто-то хочет получить последний элемент за один раз, он / она может использовать _ 1_:

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

Здесь нет необходимости хранить разделенные элементы в массиве, а затем переходить к последнему элементу. Если единственной целью является получение последнего элемента, следует использовать его.

Примечание. Это изменяет исходный массив, удаляя его последний элемент. Думайте о splice(-1,1) как о pop() функции, которая выталкивает последний элемент.

person user1144616    schedule 16.03.2012
comment
Разве это не возвращает последний элемент в массиве вместо самого последнего элемента? - person ; 29.12.2012
comment
@tozazaburo, разве это не одно и то же? - person Aram Kocharyan; 29.12.2012
comment
это изменяет массив. вы можете использовать slice (-1) вместо splice (-1), чтобы оставить исходный массив нетронутым. @AramKocharyan нет, это не так, сравните ["hi"] vs "hi". - person kritzikratzi; 20.07.2013

Этот вопрос существует уже давно, поэтому я удивлен, что никто не упомянул о том, чтобы просто вернуть последний элемент после pop().

arr.pop() столь же эффективен, как arr[arr.length-1], и оба имеют ту же скорость, что и arr.push().

Таким образом, вам могут сойти с рук:

--- ИЗМЕНИТЬ [перед нажатием убедитесь, что thePop не undefined] ---

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

--- КОНЕЦ РЕДАКТИРОВАНИЯ ---

Что может быть уменьшено до этого (та же скорость [РЕДАКТИРОВАТЬ: но небезопасно!]):

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

Это в два раза медленнее, чем arr[arr.length-1], но вам не нужно возиться с индексом. Это стоит золота в любой день.

Из решений, которые я пробовал, и кратных Единице времени выполнения (ETU) arr[arr.length-1]:

[Метод] .............. [ETU 5 элементов] ... [ETU 1 миллион элементов]

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

Последние три варианта, ОСОБЕННО [...arr].pop(), становятся ОЧЕНЬ хуже по мере увеличения размера массива. На машине без ограничений памяти моей машины [...arr].pop(), вероятно, поддерживает что-то вроде соотношения 120: 1. Тем не менее, никому не нравится пожирание ресурсов.

person Paul Parker    schedule 09.08.2018
comment
Если исходный массив может быть пустым, этот подход приведет к неправильному результату и [] будет преобразован в [undefined]. Вам нужно защитить обратный толчок явной undefined проверкой, например myPop !== undefined && arr.push(myPop) - person dhilt; 06.02.2019

Несколько способов найти последнее значение массива в javascript

  • Без изменения исходного массива

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)

let copyArr = [...arr];
console.log(copyArr.reverse()[0]);

  • Изменяет исходный массив

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

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

  • Создав собственный вспомогательный метод

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

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

console.log(arr.last);

person akhtarvahid    schedule 06.09.2019
comment
Если в вашем первом примере вы указываете Не влияя на исходный массив и выполняя как предложено: console.log(arr.reverse()[0]) - поздравляю, вы просто изменили исходный массив. - person Roko C. Buljan; 28.05.2020

Просто помещаю сюда еще один вариант.

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

Я нашел вышеупомянутый подход более понятным и коротким. Пожалуйста, не стесняйтесь попробовать это.

Примечание: он изменит исходный массив. Если вы не хотите его изменять, вы можете использовать slice()

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

Благодарим @VinayPai за указание на это.

person sidgujrathi    schedule 05.11.2019
comment
Согласно комментарию stackoverflow.com/users/510036/qix-monica-was-mistreated в этом сообщении stackoverflow.com/questions/9050345 / и тесты на jsperf.com/last-array-element2, т.е. очень медленно - person Subash; 04.03.2020
comment
.slice(-1) ответ уже давался несколько раз, начиная с в 2012 году, и его последствия подробно обсуждались (в отличие от здесь). Пожалуйста, не давайте повторяющихся ответов только для того, чтобы получить несколько голосов. - person Dan Dascalescu; 10.06.2020
comment
@DanDascalescu Спасибо за добрые слова. Это была честная ошибка, я раньше не видел этого ответа на тот же вопрос и пытался помочь тем, что знаю. Кроме того, если бы мои голоса были моими, вы бы увидели больше повторяющихся ответов в моем профиле. - person sidgujrathi; 22.06.2020
comment
@DanDascalescu В любом случае, способ поощрить новых участников на платформе и отличный способ показать свои ошибки. Престижность тебе, человек. Имея такой сильный профиль, адвокат и соучредитель очень вдохновляет, и я, конечно же, стараюсь не следовать за таким влиятельным лицом и вести себя достаточно вежливо, чтобы новым членам было комфортно. Спасибо за урок. Хороший был;) - person sidgujrathi; 22.06.2020

TL; DR

const [y] = x.slice(-1)

Объяснение:
Этот забавный синтаксис [y] = <array-or-an-object> на самом деле называется Назначение деструктуризации и согласно документации Mozilla

Синтаксис деструктурирующего присваивания - это выражение JavaScript, которое позволяет распаковывать значения из массивов или свойства из объектов в отдельные переменные

Подробнее об этом здесь

person kingbeencent    schedule 28.03.2021

Деструктуризация объекта ES6 - еще один путь.

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

Вы извлекаете свойство length из массива с помощью деструктуризации объекта. Вы создаете еще один динамический ключ, используя уже извлеченный ключ по [length-1], и назначаете его последним, все в одной строке.

person gautamits    schedule 09.03.2020
comment
Спасибо, вы можете объяснить, что именно он делает? - person Tarun Nagpal; 21.04.2020
comment
Насколько я понимаю (я мог ошибаться) length - это первый индекс массива. но [length-1] - это последний индекс (предыдущий). :last - это псевдоним, используемый для определения последнего индекса (точнее, того, который был перед первым) - person destroyer22719; 14.09.2020
comment
Массивы @TarunNagpal похожи на объекты, они имеют свойство длины и индексы как свойства. здесь мы деструктор length, затем используем имя вычисляемого свойства [length -1], чтобы получить последний элемент. - person its4zahoor; 07.01.2021

Для тех, кто не боится перегрузить прототип массива (и с маскированием перечисления не должно быть):

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

Обычно я использую underscorejs, с его помощью вы можете просто сделать

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

Для меня это более смысловое, чем loc_array.slice(-1)[0]

person niels    schedule 07.01.2014

Вот еще Javascript-арт, если вы пришли сюда в поисках

В духе другого ответа, который использовал reduceRight(), но короче:

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

Он основан на том факте, что в случае, если вы не укажете начальное значение, самый последний элемент будет выбран в качестве начального (см. Docs здесь). Поскольку обратный вызов просто продолжает возвращать начальное значение, последний элемент будет тем, который возвращается в конце.

Помните, что это следует рассматривать как искусство Javascript, и я никоим образом не рекомендую это делать, в основном потому, что он выполняется за время O (n), но также потому, что это ухудшает читабельность.

А теперь серьезный ответ

Лучший способ, который я вижу (учитывая, что вы хотите, чтобы он был более кратким, чем array[array.length - 1]), таков:

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

Тогда просто используйте функцию:

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

Функция действительно полезна в случае, если вы имеете дело с анонимным массивом, подобным [3, 2, 1, 5], используемым выше, иначе вам пришлось бы создавать его дважды, что было бы неэффективно и некрасиво:

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

Фу.

Например, вот ситуация, когда у вас есть анонимный массив, и вам нужно определить переменную, но вместо этого вы можете использовать last():

last("1.2.3".split("."));
person Lucio Paiva    schedule 16.09.2018

jQuery решает эту проблему:

> $([1,2,3]).get(-1)
3
> $([]).get(-1)
undefined
person Cees Timmerman    schedule 21.05.2013

Предложение Array.prototype.at (этап 3) добавляет метод относительной индексации (MDN):

const myArray = [1, 2, 3]

console.log(myArray.at(-1))
// => 3

Другое предложение TC39, Array.prototype.lastItem предложение (этап 1), добавляет геттер, который возвращает последний элемент в массиве:

const myArray = [1, 2, 3]

console.log(myArray.lastItem)
// => 3

Предложение .at в настоящее время реализовано только в предварительных версиях Firefox и Safari.

.lastItem не поддерживается ни в одном браузере, и в настоящее время автор предложения рассматривает возможность его отзыва.

person Richie Bendall    schedule 17.05.2020
comment
И по состоянию на 3/2021 он все еще находится в предложении и не поддерживается ни одним браузером. - person Ben Petersen; 11.03.2021
comment
Это поддерживается начиная с Firefox 88 (только Nightly) и Safari 14.1 (с jscOptions=--useAtMethod=true). Предложение lastItem, вероятно, будет снято. - person Sebastian Simon; 09.06.2021

Чтобы предотвратить удаление последнего элемента из исходного массива, вы можете использовать

Array.from(myArray).pop()

В основном поддерживается всеми браузерами (ES6)

person Alexandr Malinin    schedule 14.05.2019

В предложении ECMAScript Этап 1 предлагается добавить свойство массива, которое будет возвращать последний элемент: массив-предложение-последний.

Синтаксис:

arr.lastItem // get last item
arr.lastItem = 'value' // set last item

arr.lastIndex // get last index

Вы можете использовать polyfill.

Автор предложения: Кейт Сиркель (chai автор)

person Илья Зеленько    schedule 30.08.2018

Что бы вы ни делали, не просто используйте reverse() !!!

В нескольких ответах упоминается reverse, но не упоминается тот факт, что reverse изменяет исходный массив и не возвращает (как в некоторых других языках или фреймворках) копию.

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

Это может быть худший тип кода для отладки!

person Simon_Weaver    schedule 14.04.2019
comment
Если вам нужна перевернутая копия вашего массива, вы можете использовать оператор распространения сейчас. например [...animals].reverse() - person Josh R; 18.04.2019
comment
вы можете просто скопировать массив перед использованием обратного [1,3,4,5,"last"].slice().reverse()[0] - person Madeo; 30.05.2019

Лично я бы поддержал ответ kuporific / kritzikratzi. Метод array [array.length-1] становится очень уродливым, если вы работаете с вложенными массивами.

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]
person Michael Falck Wedelgård    schedule 03.03.2016

Я думаю, это должно работать нормально.

var arr = [1, 2, 3];
var last_element = arr.reverse()[0];

Просто переверните массив и получите первый элемент.

Изменить: как указано ниже, исходный массив будет перевернут. Чтобы этого избежать, вы можете изменить код на:

var arr = [1, 2, 3];
var last_element = arr.slice().reverse()[0];

Это создаст копию исходного массива.

person Zellius    schedule 29.03.2020
comment
Это изменит исходный массив - person Pieter; 07.04.2020
comment
Slice () копирует массив var arr = [1, 2, 3]; last_element = arr.slice (). reverse () [0]; - person Zellius; 02.04.2021
comment
@Zellius Может также просто вставить последний элемент, если вы собираетесь разрезать массив. т.е. arr.slice().pop() - person marsnebulasoup; 28.05.2021

Вы можете добавить last() функцию к Array прототипу.

Array.prototype.last = function () {
    return this[this.length - 1];
};
person trinalbadger587    schedule 20.07.2015
comment
Если вы собираетесь расширить встроенные прототипы или заполнить свойство (например, monkey-patch), сделайте это правильно: для прямой совместимости проверьте, существует ли свойство сначала , затем сделайте свойство неперечислимым, чтобы не загрязнять собственные ключи построенных объектов. В качестве методов используйте актуальные методы < / а>. Моя рекомендация: как можно точнее следуйте этим примерам, которые демонстрируют, как добавить метод, который ведет себя как другие встроенные методы. - person Sebastian Simon; 09.06.2021

В прототип Array, чтобы он доступен через все экземпляры Array.

Геттеры позволяют получить доступ к возвращаемому значению функции так же, как если бы оно было значением свойства. Возвращаемое значение функции, конечно же, последнее значение массива (this[this.length - 1]).

Наконец, вы помещаете его в условие, которое проверяет, остается ли свойство last undefined (не определено другим сценарием, который может на него полагаться).

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'

Не работает в IE ≤ 8. < / а>

person Matmarbon    schedule 06.07.2014
comment
Array.prototype.last всегда undefined? Если не работает в Chrome 36 - person bryc; 23.08.2014

ИЗМЕНЕНО:

Недавно я придумал еще одно решение, которое теперь считаю лучшим для моих нужд:

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

Теперь, когда приведенное выше определение действует, я могу сказать:

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

Название «w» означает «обертка». Вы видите, как можно легко добавить в эту оболочку другие методы, помимо last ().

Я говорю «лучше всего для моих нужд», потому что это позволяет мне легко добавлять другие подобные «вспомогательные методы» к любому встроенному типу JavaScript. На ум приходят, например, car () и cdr () Lisp.

person Panu Logic    schedule 18.03.2018
comment
Зачем использовать обертку? Если вам нужно вызвать функцию w, просто заставьте функцию вернуть последний элемент. - person fregante; 19.09.2018
comment
w([1,2,3]).length не определено. w([1,2,3])[1] не определено. Мне не кажется оберткой. И есть синтаксическая ошибка. У вас есть лишний ';'. См. stackoverflow.com/a/49725374/458321, чтобы узнать, как написать оболочку класса (класс SutString) и использовать отражение для заполнения эта обертка. Хотя, имхо, обертки - это перебор. Лучше использовать инкапсуляцию, как у вас почти есть. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Кроме того, w слишком общий. Вызов - это ArrayW или что-то в этом роде. - person TamusJRoyce; 12.08.2019

Я предлагаю создать вспомогательную функцию и использовать ее каждый раз, когда она вам понадобится. Давайте сделаем функцию более общей, чтобы иметь возможность получать не только последний элемент, но и второй от последнего и так далее.

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

Использование простое

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

Теперь давайте решим исходную проблему.

Возьмите предпоследний массив формы элементов. Если последним элементом в loc_array является «index.html», вместо этого возьмите предпоследний элемент.

Следующая строка выполняет свою работу

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

Итак, вам нужно переписать

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

в этом случае

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

или используйте дополнительную переменную для повышения удобочитаемости

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

Я думаю, что самый простой для понимания для новичков и сверхнеэффективный способ: ????

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".
person Erdi    schedule 27.10.2014
comment
Это решение требует на O (n) больше памяти и времени O (n). Это действительно не идеальное решение. - person hlin117; 06.07.2015
comment
он не должен начинаться с фенербахче. это должно быть так: [бесиктас, галатасарай, трабзонспор, бурсаспор, фенербахче];) - person kodmanyagha; 19.05.2021

Как насчет чего-то вроде ниже:

if ('index.html' === array[array.length - 1]) {  
   //do this 
} else { 
   //do that 
}

Если вы используете Underscore или Lodash, вы можете использовать _.last(), например:

if ('index.html' === _.last(array)) {  
   //do this 
} else { 
   //do that 
}

Или вы можете создать свою последнюю функцию:

const _last = arr => arr[arr.length - 1];

и используйте его как:

if ('index.html' === _last(array)) {  
   //do this 
} else { 
   //do that 
}
person Alireza    schedule 31.01.2019

Это сработает?

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])));
}
person balexander    schedule 09.07.2010
comment
Нет, потому что .pop() возвращает последний элемент, а также удаляет его, поэтому ваши индексы меняются. - person Aaron Harun; 09.07.2010
comment
Если вы не хотите, чтобы исходный массив изменялся, выполните arr.slice().pop() - это создаст новый массив - person Deepak Kamat; 11.03.2018
comment
лучше, когда вы больше не заботитесь о массивах! - person Sabir Hossain; 29.06.2020

Используя оператор распространения ES6 / ES2015 (...), вы можете сделать следующее.

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

Обратите внимание, что с помощью оператора распространения и обратного преобразования мы не изменили исходный массив, это чистый способ получить последний элемент массива.

person Vlad Bezden    schedule 17.03.2017
comment
Обращение всего массива только для того, чтобы получить последний элемент, очень неэффективно. - person slang; 16.04.2017
comment
@slang, согласен. Если вы выполняете сотни или миллионы операций, вам следует подумать о том, чтобы не делать этого таким образом, но если вам нужно сделать это только несколько раз, то этого никто не заметит. Этот пример обеспечивает «чистый» вызов без изменения фактического массива данных. - person Vlad Bezden; 16.04.2017

Использование lodash _.last (array) Получает последний элемент массива.

data = [1,2,3]
last = _.last(data)
console.log(last)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

person Deano    schedule 20.09.2017

Это можно сделать с помощью lodash _.last или _ 2_:

var data = [1, 2, 3, 4]
var last = _.nth(data, -1)
console.log(last)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

person Penny Liu    schedule 22.11.2018

Функциональное программирование с Ramda

Если вы используете JS, я бы посоветовал проверить Ramda, библиотеку функционального программирования (например, Lodash и Underscore, за исключением более продвинутых и модульных). Ramda предоставляет это с помощью R.last

import * as R from 'ramda';
R.last(['fi', 'fo', 'fum']); //=> 'fum'
R.last([]); //=> undefined

R.last('abc'); //=> 'c'
R.last(''); //=> ''

Кроме того, он предоставляет init, head, tail. Список монстров из (Learn You a Haskell)

Список монстров

person Evan Carroll    schedule 31.12.2018
comment
включение библиотеки нецелесообразно для получения последнего элемента, если я это сделаю, я бы использовал underscorejs.org/#last - person Tebe; 17.01.2019
comment
@Tebe Ramda - это более новая, более современная и модульная версия Lodash, которая заменяет Underscore.js - person Evan Carroll; 17.01.2019
comment
да, я попробовал рамду, она показалась мне немного не слишком сложной на первый взгляд. Возможно, я все еще не думаю, что это достаточно функционально, и займусь этим, когда мой разум будет к этому готов. Кстати, я вижу, у вас есть опыт с этим, как бы выглядел такой код в рамде? _.chain ([1,2,3]). map ((val) = ›{return val * 2}). first (). value () -› result is 2. Поддерживает ли он цепочку? Я вижу, что у ramda есть цепочка методов, но похоже, что это для чего-то еще - person Tebe; 17.01.2019
comment
@Tebe Как это R.pipe(R.take(1), x=>x*2) (также работает с машинописным текстом) - person Evan Carroll; 17.01.2019
comment
потребует ли этот код большего количества злых вложений, если мы добавим больше цепочек? Например, __. Chain ([1,2,3]). Map ((val) = ›{return val * 2}) .filter ((val) =› {return val ›3;}) .map ((val) = ›{Return val * 2}) .first () .value () - paste.debian.net/1061022 (см. ссылку с форматированным кодом) - результат 8 - person Tebe; 17.01.2019
comment
Нет, Pipe выполняет несколько функций const m = x => y => x * y; R.pipe(R.take(1), m(2), m(3), m(4)) Какой здесь смысл? Я имею в виду, что я помогу тебе изучить Рамду, но это не имеет отношения к моему ответу? И похоже, что тебе немного обидно, что ты изо всех сил пытаешься понять Рамду, поэтому ты проголосовал против меня (не лучший способ начать разговор). Продолжайте учиться. Кстати, вы также можете сделать x = R.pipe( R.take(1), y=>y*2 ); y = R.pipe( x, z => z*2 ) - person Evan Carroll; 17.01.2019
comment
Каким бы ни был Тревор, к сожалению, нет никакого способа вернуть это обратно. Я собираюсь проголосовать за другой за ваш ответ, если он заставит вас почувствовать себя лучше. Кстати, сейчас я не пытаюсь его изучать, я просто пытался выделить то, что упускает рамда и что удерживало меня в Underscore / Backbone. Определение другой функции в переменной temp - это возня вместо того, чтобы скрывать вещи внутри цепочки. - person Tebe; 17.01.2019
comment
На самом деле, вам не нужно этого делать, я бы никогда этого не сделал в вашем случае, я бы просто протрубил больше чем одну вещь. Дело в том, что ramda выполняет композицию функций с помощью pipe. А Lodash оборачивает объект в базовый класс, который предоставляет операторы как методы. Метод Lodash - очень плохая идея. Причина, по которой они это делают, заключается в том, что унаследованный код, использующий Lodash. Например, Rxjs раньше делали то же самое, но теперь они также используют метод pipe. - person Evan Carroll; 17.01.2019
comment
Одним из замечательных практических преимуществ метода pipe является то, что любая библиотека может экспортировать функции, которые работают с pipe, и вам нужно импортировать только то, что вы используете. Вдобавок все импортированное, что вы не используете, подвержено встряхиванию дерева, которое Webpack может фактически удалить в пакете (мертвый код исчезает). Это делает метод Рамба более чистым (функционально), более кратким (посмотрите на мой пример), более быстрым (без упаковки объектов) и меньшим размером (нет необходимости импортировать класс или все операторы, и вы можете удалить операторы, которые вы не используете автоматически) - person Evan Carroll; 17.01.2019
comment
@Tebe, если с невозможно вернуть, вы имеете в виду отрицательный голос, конечно, можете. Если пользователь редактирует ответ, вы можете отозвать свой отрицательный голос. - person ypercubeᵀᴹ; 17.01.2019
comment
Еще раз спасибо. Таким образом, похоже, что функциональное программирование имеет много сторон, Рамда просто проповедует еще один способ, о котором я не знал раньше. Хотя не уверен в плохой цепочке. Это уже заложено в основу ES6. Например. [1,2,3] .filter ((val) = ›{return val› 1;}). Map ((val) = ›{return val * 2;}). Push () -› возвращает 2. Я вообще начал это преобразование, потому что помню, как несколько лет назад задавался вопросом, когда я хотел перейти на ramda и не нашел такой необходимости в FP, как цепочка IMHO. Модульность и продвинутость - это нормально (если это действительно так), хотя я бы сделал ставку на удобство использования. - person Tebe; 18.01.2019
comment
@Tebe, но зло этого метода, несмотря на принятие ES6, довольно очевидно, например, чтобы найти ключи объекта, который вы не делаете a.keys(), вы делаете Object.keys(a)? Почему? Потому что, вероятно, где-то кто-то расширил Object.prototype, чтобы уже иметь keys, и es не хотел нарушать обратную совместимость. Однако с методом Ramda это не проблема. R.pipe(R.keys, R.join(''))( {foo:1,bar:2} ); Вы просто составляете функции вместе. - person Evan Carroll; 18.01.2019
comment
Более того, с помощью ramda и lodash (и, надеюсь, не с es6) люди создают библиотеки для расширения основных функций. Расширение прототипа обычно считается плохим. Вот почему забавно, что команда lodash подумала, что было бы неплохо воссоздать эту проблему, заставив все объекты, которые их операторы принимают экземпляры класса-оболочки. (к которому любое расширение lodash должно было бы применить патч обезьяны). - person Evan Carroll; 18.01.2019
comment
Я не понимаю, почему этот ответ получил столько голосов против! Ramda, возможно, лучше, чем Lodash и Underscore. Он чисто функциональный и чистый, хотя его может быть немного сложно понять, если кто-то не привык к функциональному программированию. Это определенно хороший ответ на проблему, хотя я бы все равно не рекомендовал использовать библиотеку, если единственное, что вам нужно сделать, это получить последний элемент в массиве. - person Yathi; 09.03.2019
comment
За рамками вопроса. Включены Lodash и Underscore. Рамда полон сокращений и жаргона. Лучше подходит для использования реального функционального языка + llvm / emscripten для создания веб-сборки. Что по-прежнему выходит за рамки. - person TamusJRoyce; 07.08.2019

Обновление 2020

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

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

console.log(a.last());
// [ 4, 5 ]
console.log(a.last().last());
// 5

Сеттер и геттер

Array.prototype.last = function(val=null) {
  if (this.length === 0) {
    if (val) this[0] = val;
    else return null; 
  }
  
  temp = this;
  while(typeof temp[temp.length-1] === "object") {
    temp = temp[temp.length-1];
  }
  
  if (val) temp[temp.length-1] = val; //Setter  
  else return temp[temp.length-1]; //Getter
  
}

var arr = [[1, 2], [2, 3], [['a', 'b'], ['c', 'd']]];
console.log(arr.last()); // 'd'
    
arr.last("dd"); 
console.log(arr); // [ [ 1, 2 ], [ 2, 3 ], [ [ 'a', 'b' ], [ 'c', 'dd' ] ] ]
person Weilory    schedule 25.10.2020
comment
Пожалуйста, избегайте загрязнения прототипов. - person sean; 19.11.2020
comment
@Sean, добавление - лучшая практика по сравнению с переписыванием прототипа. - person Weilory; 20.11.2020
comment
Я не знаю, что вы пытаетесь сказать, но изменение прототипов, которыми вы не владеете, делает ваш код склонным к конфликтам и ухудшает прямую совместимость. Загрязнение прототипов - это известная плохая практика, обнаруженная бюллетенями по безопасности JavaScript. - person sean; 21.11.2020

Вы можете решить эту проблему также, не извлекая массив из URL-адреса

Это моя альтернатива

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

!Привет

person snaphuman    schedule 15.09.2014

Другой вариант только ES6 - использовать Array.find(item, index)=> {...}) следующим образом:

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

небольшая практическая ценность, опубликованная, чтобы показать, что индекс также доступен для вашей логики фильтрации.

person Simple.Js    schedule 14.01.2018

Это чисто и эффективно:

let list = [ 'a', 'b', 'c' ]

(xs => xs[xs.length - 1])(list)

Если вы установите оператор канала с помощью Babel, он станет:

list |> (xs => xs[xs.length - 1])
person sdgfsdh    schedule 11.12.2017
comment
Мне очень нравится этот синтаксис iife. Спасибо, что усложнили мою жизнь, к счастью. - person Ben Steward; 18.10.2018

Этот метод не повредит вашему прототипу. Он также защищает от массивов длины 0 вместе с массивами _2 _ / _ 3_. Вы даже можете переопределить значение по умолчанию, если возвращаемое значение по умолчанию может соответствовать элементу в вашем массиве.

const items = [1,2,3]
const noItems = []

/**
 * Returns the last item in an array.
 * If the array is null, undefined, or empty, the default value is returned.
 */
function arrayLast (arrayOrNull, defVal = undefined) {
  if (!arrayOrNull || arrayOrNull.length === 0) {
    return defVal
  }
  return arrayOrNull[arrayOrNull.length - 1]
}

console.log(arrayLast(items))
console.log(arrayLast(noItems))
console.log(arrayLast(null))

console.log(arrayLast(items, 'someDefault'))
console.log(arrayLast(noItems, 'someDefault'))
console.log(arrayLast(null, 'someDefault'))

person Steven Spungin    schedule 27.10.2018

Также есть модуль npm, который добавляет last в Array.prototype

npm install array-prototype-last --save

использование

require('array-prototype-last');

[1, 2, 3].last; //=> 3 

[].last; //=> undefined 
person qiAlex    schedule 28.07.2017
comment
источник функции? - person Matrix; 01.08.2017
comment
это сималар к этому? Array.prototype.last = function(){ return this[this.length - 1]; } + Object.defineProperty(Array.prototype, 'last', {enumerable: false}); - person Matrix; 01.08.2017
comment
в вашем примере last - это функция, вы должны называть ее как ['a', 'b']. last () // 'b', а в модуле last - свойство, и вы можете называть его как ['a', 'b' ] .last // 'b' - person qiAlex; 01.08.2017
comment
хорошо, убрать () в коде сложно, но это свойство остается функцией, вызываемой каждый раз, не так ли? - person Matrix; 01.08.2017

стрелочная функция обеспечивает самую быструю работу метод более краткий, не повторяя имя массива.

var lastItem = (a => a[a.length - 1])(loc_array);
person Joshua Fan    schedule 03.08.2017
comment
Но зачем писать метод, если можно получить прямой доступ к последнему элементу ... var lastItem = a[a.length-1] - person Kokodoko; 01.01.2018
comment
Однако это не демонстрирует создание метода. Он демонстрирует использование стрелочной функции для переименования loc_array в a в контексте функции. Это похоже на var getLast = a => a[a.length - 1]; var lastItem = getLast(loc_array), но функция getLast встроена, а не определена отдельно. - person Florrie; 22.11.2018


Обычно вы не должны связываться с прототипом встроенных типов, но вот хитрость / ярлык:

Object.defineProperty(Array.prototype, 'last', {
  get() {
    return this[this.length - 1]; 
  }
});

Это позволит всем объектам массива иметь свойство last, которое вы можете использовать следующим образом:

const letters = ['a', 'b', 'c', 'd', 'e'];
console.log(letters.last); // 'e'

Вы не должны связываться с прототипом встроенного типа, потому что никогда, когда будет выпущена новая версия ES, и в случае, если новая версия использует то же имя свойства, что и ваше настраиваемое свойство, могут произойти всевозможные сбои. Вы МОЖЕТЕ сделать свойство чем-то, что, как вы знаете, должно быть в версии ES, например lastItem, но это остается на усмотрение разработчика.

person ryanwaite28    schedule 24.11.2020

Используя reduceRight:

[3,2,1,5].reduceRight((a,v) => a ? a : v);
person niedomnie    schedule 04.04.2016
comment
На самом деле это довольно творческий способ сделать это, хотя он выполняется за O (n) раз, потому что он все еще проходит через весь массив. - person Lucio Paiva; 16.09.2018
comment
Если вы не возражаете, я сделал его еще более кратким, убрав ненужные return и фигурные скобки. - person Lucio Paiva; 16.09.2018

Самый простой способ получить последний элемент массива:

var last_item = loc_array.reverse()[0];

Конечно, нам нужно сначала убедиться, что в массиве есть хотя бы один элемент.

person Cong Nguyen    schedule 22.11.2018
comment
Это не дает ответа на вопрос. Чтобы критиковать или запрашивать разъяснения у автора, оставьте комментарий под его сообщением. - Из отзыва - person Vizllx; 22.11.2018
comment
Вопрос в том, как получить последний элемент в массиве, и мое решение должно работать. :) - person Cong Nguyen; 22.11.2018
comment
это самый медленный способ получить последний элемент ... что, если в массиве миллион элементов? - person Deian; 14.12.2018
comment
Ужасная ужасная идея! reverse изменяет исходный массив, поэтому если вы запустите его дважды подряд, вы получите разные результаты (например, длина> 1) - person Simon_Weaver; 14.04.2019

простой ответ

const array = [1,2,3]
array[array.length - 1]
person destroyer22719    schedule 14.08.2020

для доступа к последнему элементу в массиве с помощью C # мы можем использовать GetUpperBound (0)

(0) в случае, если этот одномерный массив

my_array[my_array.GetUpperBound(0)] //this is the last element in this one dim array
person Sherief Zakaria    schedule 25.10.2019
comment
Вопрос был в том, как это сделать в JavaScript :) - person Lucas Caton; 27.10.2019

array.reverse()[0]

Это так просто

person Abhishek Choudhary    schedule 31.07.2019
comment
Reverse изменяет исходный массив. Для этого метода следует вызвать Array.from (items) .reverse () [0]. - person TamusJRoyce; 07.08.2019
comment
Это приводит к таким ненужным накладным расходам. Даже с предложением @TamusJRoyce это все равно плохо, я бы не стал использовать его даже для массива, который гарантированно содержит не более двух элементов. - person VLAZ; 26.09.2019