到目前为止,这是我的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",如果是,请改为抓取倒数第三项。

#1 楼

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


如果您的服务器为“ index.html”和“ inDEX.htML”提供相同的文件,您也可以使用:.toLowerCase()

但是,您可以想考虑如果可能的话在服务器端进行操作:这将更加清洁,并且适合没有JS的用户。


评论


如果只需要最后一个项目,可以Array.pop()

–巴德里·达拉克尚(Badri Derakhshan)
6月7日6:54

@BadriDerakhshan这将不可避免地在返回数组之前从数组中删除最后一个元素,因此,如果您只想检查数组的最后一个元素,则这不是一个选择。您还必须将其推回以将阵列还原到以前的状态。

–罗比杜
11月1日下午13:02

#2 楼

不知道是否有缺点,但这看起来很简洁:

arr.slice(-1)[0] 




arr.slice(-1).pop()


如果数组为空,则返回undefined

评论


使用解构也很好:const [lastItem] = arr.slice(-1)

– Diachedelic
19年3月11日在6:30

.pop()删除最后一个修改原始数组的元素。这与简单地获取该值不同。

–灌木丛
5月6日14:38

@Badrush slice()使用单个元素的副本创建新数组,然后pop仅修改该副本。原始阵列保持不变

– kritzikratzi
5月7日18:21

@mvmn我很久以前就做过基准测试,单个2.4ghz线程的吞吐量大约是每秒一百万次。因此,除非您有解决问题的方法,否则无论如何都不应该在JS中解决,否则不会引起注意(与arr [arr.length-1]相比,iirc速度降低了50-100x)

– kritzikratzi
6月2日18:54

@Govan,请参阅我的评论。您可以将其称为每秒过多的次数。如果您需要更多资源,或者有可用的阵列长度,请使用常规阵列访问以获取最佳性能arr [arr.length-1]

– kritzikratzi
6月22日20:14

#3 楼

使用Array.pop:

var lastItem = anArray.pop();


重要提示:这将返回最后一个元素并将其从数组中删除

#4 楼

@chaiguy发布的内容的简短版本:

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


读取-1索引已返回undefined

编辑:

这些天,人们似乎更倾向于使用模块,以避免接触原型或使用全局名称空间。

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


评论


如果不清楚如何实际使用它,请看以下示例:var lastItem = [3,2,1,5] .last();。 lastItem的值为5。

–user128216
2015年12月5日在2:23

这个答案是正确的,但也很干净BUT(!!!)使用Javascript的经验法则是,请勿修改您不拥有的对象。由于许多原因,这很危险,例如1.团队中的其他开发人员可能会感到困惑,因为此方法不是标准的。2.在库中进行任何更新,甚至使用较低或较高版本的ECMAScript,都可能很容易丢失!

–法尔扎德YZ
16-10-13在16:21

对于任何想知道的人,这都会破坏Array.forEach()。我仍然同意修改原型并不是最糟糕的事情,但这是不好的。

– Seph Reed
17-10-25在20:57

Imo修改Array.prototype没有太大的问题,但是您应该使用Object.assign(Array.prototype,'last',{value:function(){…}});;。否则,该属性将是可枚举的。

–黄雨伞
18-09-6在9:39



#5 楼

有两种选择:

var last = arr[arr.length - 1]




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


前者更快,但是后者看起来更好

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

评论


感谢您的jsperf链接。从性能的角度来看,第二个选项是胡说八道。

– Leos Literak
7月5日19:28

第一种选择也很明显。第二个没有那么多

–set
8月10日7:14

#6 楼

这是在不影响原始阵列的情况下获取它的方法。

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 


评论


您应该执行slice(-1).pop(),否则将复制整个数组(实际上只需要复制最后一个元素)。

– kritzikratzi
15年5月29日在23:46

那么就不需要该pop()了:只需做arr.slice(-1)[0]

–克里斯托弗·马洛伊斯(Christophe Marois)
17年4月12日在5:48

#7 楼

最干净的ES6方式(IMO)为:

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


如果我们不使用扩展运算符,则可以避免像foo那样改变.pop()
也就是说,我也喜欢foo.slice(-1)[0]解决方案。

评论


您还可以使用数组解构使它更像ES6;)stackoverflow.com/a/46485581/31671

– alex
17-10-4在7:52

请注意,此解决方案执行整个阵列的副本。

–布兰登·安纳布尔(Brendan Annable)
18年7月3日在1:56

它与.slice(-1)[0]一样不可读,但速度较慢。最好使用.slice

–fregante
18年9月19日在4:30

复制整个数组仅用于“干净”语法对我来说似乎很愚蠢。它甚至看起来都不太好

–杰玛·琼斯(Jemar Jones)
18/12/13在15:55

#8 楼

我宁愿使用array.pop()而不是索引。

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


这样,您总是可以得到index.html之前的元素(前提是您的数组将index.html隔离为一项) )。注意:不过,您将丢失数组中的最后一个元素。

#9 楼

性能
今天2020.05.16我在MacOs High Sierra v10.13.6上的Chrome v81.0,Safari v13.1和Firefox v76.0上执行所选解决方案的测试
结论


建议将arr[arr.length-1](D)作为最快的跨浏览器解决方案
可变的arr.pop()(A)和不可变的_.last(arr)(L)较快
对于长字符串,解决方案I,J较慢
解决方案H,K(jQuery)在所有浏览器中最慢


详细信息
我测试了两种情况的解决方案:可变:A,
B,


不可变:D,
E,
H,
I,
J(我的),



不能从外部库中更改:K,
L,
M,


两种情况

短字符串-10个字符-您可以在此处运行测试

长字符串-1M个字符-您可以在此处运行测试





 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的示例结果


#10 楼

const [lastItem] = array.slice(-1);带有-1的Array.prototype.slice可用于创建仅包含原始Array的最后一项的新Array,然后可以使用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 




评论


从2012年开始,已经多次给出.slice(-1)答案,其含义已在详细讨论中(与此处不同)。请不要重复回答,只是为了获得点赞。

– Dan Dascalescu
6月10日5:22

我最喜欢这个答案。我见过的其他.slice(-1)答案使用[0]而不是解构。 @diachedelic的评论暗示了这种破坏,但我认为它应该是一个答案,而不是评论。很好的例子和链接。

–马库斯
10月29日16:58

#11 楼

您可以使用此模式...

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


虽然它读起来很不错,但是请记住,它创建了一个新数组,因此效率不如其他解决方案,但是它将几乎永远不会成为您应用程序的性能瓶颈。

#12 楼

可以使用带负值的slice方法来获得数组的最后一项。

您可以在底部了解更多信息。

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


使用pop()会更改数组,但这并不总是一个好主意。

评论


不过,Slice会返回一个数组,因此请使用arr.slice(-1)[0],像这样的答案。

– Cees Timmerman
13年5月21日在10:31



如果性能是一个问题,请知道此方法比array [array.length-1]慢很多jsperf.com/get-last-item-from-array/13

–布鲁诺·佩雷斯(Bruno Peres)
17 Mar 8 '17 at 2:54

#13 楼

这个问题已经存在很长时间了,所以令我惊讶的是,没有人提到在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]的两倍,但是您不必在索引中四处寻找。每天都值得黄金。

我尝试过的解决方案中,以arr[arr.length-1]的执行时间单位(ETU)的倍数:

[方法] ......... ..... [ETUs 5 elems] ... [ETU 1百万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 :)


最后三个选项,尤其是[...arr].pop(),由于数组的大小增加。在没有内存限制的计算机上,[...arr].pop()可能会保持120:1的比率。不过,没有人喜欢资源消耗。

评论


如果初始数组可以为空,则此方法将导致错误结果,并且[]将变为[undefined]。您需要使用显式未定义检查来保护向后推送,例如myPop!== undefined && arr.push(myPop)

–污点
19年2月6日在8:36



#14 楼

如果要一次性获取最后一个元素,则可以使用Array#splice()

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


这里,不需要将拆分的元素存储在数组中,然后转到最后一个元素。如果获取最后一个元素是唯一的目标,则应使用此元素。

注意:这将通过删除其最后一个元素来更改原始数组。将splice(-1,1)视为弹出最后一个元素的pop()函数。

评论


这不是返回数组中的最后一个元素,而不是最后一个元素本身吗?

–user663031
2012年12月29日在7:02

@tozazaburo是不是同一回事?

–阿拉姆·科恰良(Aram Kocharyan)
2012年12月29日15:34

这将修改数组。您可以使用slice(-1)代替splice(-1)保持原始数组不变。 @AramKocharyan不,不是,比较[“ hi”]与“ hi”。

– kritzikratzi
13年7月20日在0:29

#15 楼

只需在此处添加另一个选项即可。

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


我发现上述方法更简洁,在线更简短。

注意:它将修改原始数组,如果不想修改它,可以使用slice()

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


感谢@VinayPai指出这一点。

评论


根据stackoverflow.com/users/510036/qix-monica-was-misfused在这篇文章上的评论stackoverflow.com/questions/9050345/…和jsperf.com/last-array-element2上的测试非常慢

– Subash
3月4日下午3:59

从2012年开始,已经多次给出.slice(-1)答案,其含义已在详细讨论中(与此处不同)。请不要重复回答,只是为了获得点赞。

– Dan Dascalescu
6月10日5:25

@DanDascalescu谢谢您的客气话。这是个老实的错误,我之前在相同的问题上都没有看到这个答案,而是试图帮助我了解。此外,如果支持者是我的摩托车,那么您会在我的个人资料上看到更多重复的答案。

– sidgujrathi
6月22日12:39

@DanDascalescu鼓励平台上新成员的任何方式,以及显示错误的绝佳方法。谢谢你们倡导者,联合创始人具有如此高的知名度,他非常鼓舞人心,我当然不要试图跟随这样的影响者,并保持礼貌以使新成员感到舒适。感谢您的教训。这是一个好;)

– sidgujrathi
6月22日12:42

#16 楼

对于那些不怕使Array原型过载的人(并且不应该使用枚举掩码):

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


#17 楼

如果您是来这里寻求帮助的,这是更多的Java艺术,

本着另一个使用reduceRight()的答案的精神,但更简短:

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


它依赖于以下事实:如果您不提供初始值,则会选择最后一个元素作为初始值(请在此处查看文档)。由于回调只是不断返回初始值,所以最后一个元素将是最后返回的元素。

请注意,这应该被视为Java语言,绝不是我建议的方式它,主要是因为它在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("."));


#18 楼

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

从性能角度来看,这是最佳选择(比arr.slice(-1)快1000倍)。

评论


这如何增加最佳答案?

– Dan Dascalescu
6月10日5:25

#19 楼

jQuery巧妙地解决了这个问题:

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


#20 楼

我通常使用underscorejs,有了它,您就可以执行

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


对我来说,比loc_array.slice(-1)[0]更语义

#21 楼

ES6对象销毁是另一种可行的方法。




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





使用对象分解从Array中提取length属性。您可以使用[length-1]提取的密钥来创建另一个动态密钥,并将其分配到最后一行。

评论


谢谢,您能解释一下它的确切作用吗?

– Tarun Nagpal
4月21日,下午2:26

从我的理解(我可能错了),长度是数组的第一个索引。但是[length-1]是最后一个索引(之前的索引)。 :last是用来定义最后一个索引的别名(或者确切地说是第一个索引之前的索引)

–destroyer22719
9月14日14:48



#22 楼

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




评论


如果在第一个示例中声明“不影响原始数组”并按照建议进行操作:console.log(arr.reverse()[0])-恭喜,您刚刚修改了原始数组。

– Roko C. Buljan
5月27日22:28



#23 楼

在ECMAScript建议阶段1中,建议添加一个数组属性,该属性将返回最后一个元素:proposal-array-last。

语法:

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

arr.lastIndex // get last index


您可以使用polyfill。

提案作者:Keith Cirkel(柴老师)

#24 楼

为了防止从原始数组中删除最后一项,您可以使用

 Array.from(myArray).pop()
 


所有浏览器都支持(ES6)

#25 楼

无论做什么,都不要只使用reverse() !!!
一些答案​​提到了reverse,但是没有提到reverse修改了原始数组,并且(不像其他语言或框架那样)返回了一个事实。复制。
var animals = ['dog', 'cat'];

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

这可能是最差的代码调试类型!

评论


如果确实需要阵列的反向副本,则可以立即使用散布运算符。例如[... animals] .reverse()

–乔什·R(Josh R)
19年4月18日在5:24

您可以在使用反向[1,3,4,5,“ last”]。slice()。reverse()[0]之前简单地复制数组

–Madeo
19年5月30日在4:01



#26 楼

我个人会赞成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]


#27 楼

您可以在last()原型中添加Array函数。

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


#28 楼

您可以在Array的原型中添加一个新的属性getter,以便可以通过Array的所有实例进行访问。

Getters允许您访问函数的返回值,就像它是财产。函数的返回值当然是数组的最后一个值(this[this.length - 1])。最后,将其包装在检查last -property是否仍为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中不起作用。

评论


Array.prototype.last总是不确定的吗?如果在Chrome 36下无法使用

– bryc
2014年8月23日下午16:43

#29 楼

尚未实现!
新的TC39 Array.prototype.lastItem建议(阶段1)添加了一个吸气剂,该吸气剂返回数组中的最后一项:
 const myArray = [1, 2, 3]

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

Array.prototype.item提案(第3阶段)添加了一个不同的API:
 const myArray = [1, 2, 3]

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


评论


可能是因为这是第一阶段的提案

–里奇·本德尔(Richie Bendall)
6月7日20:14

#30 楼

编辑:

最近我想出了另外一种解决方案,现在我认为这是最适合我的需要:

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


具有上述定义实际上,我现在可以说:

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


名称“ w”代表“包装器”。
您会看到如何轻松地在此包装器中添加除'last()'之外的更多
方法。

我说“最适合我的需求”,因为这允许
/>我可以轻松地将其他此类“帮助方法”添加到任何JavaScript内置类型中。
想到的是
实例的Lisp的car()和cdr()。

评论


为什么要使用包装纸?如果必须调用w函数,只需使该函数返回最后一项即可。

–fregante
18年9月19日在4:32

w([1,2,3])。length未定义。 w([1,2,3])[1]未定义。对我来说似乎不像是包装纸。并且存在语法错误。您还有一个额外的“;”。有关如何编写类包装器(SutString类)以及如何使用反射来填充该包装器的信息,请参见stackoverflow.com/a/49725374/458321。不过,恕我直言,包装器是过大的。更好地使用封装,就像您几乎拥有的一样。 return {arr:anArray,last(){return anArray [anArray.length-1]; }};。同样,w太通用了。调用是ArrayW之类的。

– TamusJRoyce
19年8月11日在22:40