到目前为止,这是我的 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"
,如果是,则改为获取倒数第三项。
if (loc_array[loc_array.length - 1] === 'index.html') {
// do something
} else {
// something else
}
如果您的服务器为“index.html”和“inDEX.htML”提供相同的文件,您也可以使用:.toLowerCase()
。
不过,如果可能的话,你可能会考虑在服务器端做这个:它会更干净,并且适合没有 JS 的人。
编辑-ES-2022
使用 ES-2022 Array.at()
,上面的代码可以这样写:
if (loc_array.at(-1) === 'index.html') {
// do something
} else {
// something else
}
不确定是否有缺点,但这似乎很简洁:
arr.slice(-1)[0]
或者
arr.slice(-1).pop()
如果数组为空,两者都将返回 undefined
。
const [lastItem] = arr.slice(-1)
arr[arr.length-1]
使用 Array.pop:
var lastItem = anArray.pop();
重要:这将返回最后一个元素并将其从数组中删除
filename.split('.').pop()
const lastItem = [...anArray].pop()
将是避免突变的一种方法
@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
。
Do NOT modify objects you Do NOT own
。由于许多原因,它很危险,例如 1. 在您的团队中工作的其他开发人员可能会感到困惑,因为这种方法不是标准的 2. 库中的任何更新,甚至使用更低或更高的 ECMAScript 版本都可能很容易丢失!
Array.prototype
没有那么大的问题,但您应该使用 Object.assign(Array.prototype, 'last', { value: function () { … } });
。否则,该属性将是可枚举的。
两个选项是:
var last = arr[arr.length - 1]
或者
var last = arr.slice(-1)[0]
前者更快,但后者看起来更好
http://jsperf.com/slice-vs-length-1-arr
表现
今天 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) 在所有浏览器上最慢
https://i.stack.imgur.com/smISX.png
细节
我测试了两种解决方案:
可变:A,B,C,
不可变:D、E、F、G、H、I、J(我的),
从外部库不可变:K、L、M、
两种情况
短字符串 - 10 个字符 - 你可以在这里运行测试
长字符串 - 1M 个字符 - 你可以在这里运行测试
函数 A(arr) { 返回 arr.pop(); } 函数 B(arr) { 返回 arr.splice(-1,1); } 函数 C(arr) { 返回 arr.reverse()[0] } 函数 D(arr) { 返回 arr[arr.length - 1]; } 函数 E(arr) { return arr.slice(-1)[0] ; } 函数 F(arr) { 让 [last] = arr.slice(-1);最后返回; } 函数 G(arr) { 返回 arr.slice(-1).pop(); } 函数 H(arr) { 返回 [...arr].pop(); } 函数 I(arr) { return arr.reduceRight(a => a); } function J(arr) { return arr.find((e,i,a)=> a.length==i+1); } 函数 K(arr) { 返回 $(arr).get(-1); } 函数 L(arr) { 返回 _.last(arr); } 函数 M(arr) { return _.nth(arr, -1); } // ---------- // 测试 // ---------- 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));
短字符串的 Chrome 示例结果
https://i.stack.imgur.com/VYUMF.png
以下是如何在不影响原始 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
pop()
:只需执行arr.slice(-1)[0]
“最干净”的 ES6 方式(IMO)将是:
const foo = [1,2,3,4];
const bar = [...foo].pop();
如果我们不使用扩展运算符,这可以避免像 .pop()
那样改变 foo
。
也就是说,我也喜欢 foo.slice(-1)[0]
解决方案。
.slice(-1)[0]
一样不可读,但速度较慢。不妨使用 .slice
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
.slice(-1)
答案,其含义已详细讨论(与此处不同)。请不要为了获得一些支持而给出重复的答案。
const [y] = x.slice(-1)
快速说明:这种语法 [y] =
arr[arr.length - 1]
肯定更好,因为它在大多数浏览器上更具可读性和快一个数量级。
我宁愿使用 array.pop()
而不是索引。
while(loc_array.pop()!= "index.html"){
}
var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length])));
这样,您始终可以获取 index.html 之前的元素(前提是您的数组已将 index.html 隔离为一项)。注意:不过,您将丢失数组中的最后一个元素。
您可以对 Array#at
使用相对索引:
const myArray = [1, 2, 3]
console.log(myArray.at(-1))
// => 3
jscOptions=--useAtMethod=true
)。 lastItem
提案可能会被撤回。
const lastElement = myArray[myArray.length - 1];
从性能的角度来看,这是最好的选择(比 arr.slice(-1)
快约 1000 倍)。
你可以使用这个模式...
let [last] = arr.slice(-1);
虽然它读起来相当不错,但请记住它创建了一个新数组,因此它的效率低于其他解决方案,但它几乎永远不会成为应用程序的性能瓶颈。
如果想一次性获得最后一个元素,他/她可以使用 Array#splice()
:
lastElement = document.location.href.split('/').splice(-1,1);
在这里,不需要将拆分的元素存储在一个数组中,然后到达最后一个元素。如果获取最后一个元素是唯一的目标,则应该使用它。
注意:这会通过删除其最后一个元素来更改原始数组。将 splice(-1,1)
视为弹出最后一个元素的 pop()
函数。
["hi"]
和 "hi"
。
在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));
通过创建自己的辅助方法
让 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])
- 恭喜,您刚刚修改了原始数组。
可以通过使用带负值的 slice 方法来获取数组的最后一项。
您可以在底部阅读有关它的更多信息here。
var fileName = loc_array.slice(-1)[0];
if(fileName.toLowerCase() == "index.html")
{
//your code...
}
使用 pop() 会改变你的数组,这并不总是一个好主意。
arr.slice(-1)[0]
,如 this answer。
array[array.length - 1]
jsperf.com/get-last-item-from-array/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) 的倍数计算:
[方法].......[ETU 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]
。您需要使用明确的 undefined
检查来保护向后推送,例如 myPop !== undefined && arr.push(myPop)
只是在这里放另一个选择。
loc_array.splice(-1)[0] === 'index.html'
我发现上述方法在网上更简洁、更简短。请随意尝试这个。
注意:它会修改原始数组,如果不想修改可以使用slice()
loc_array.slice(-1)[0] === 'index.html'
感谢@VinayPai指出这一点。
.slice(-1)
答案,其含义已详细讨论(与此处不同)。请不要为了获得一些支持而给出重复的答案。
ES6 对象解构是另一种方法。
const {length, [length-1]: last}=[1,2,3,4,5] console.log(last)
您可以使用对象解构从 Array 中提取长度属性。您使用已通过 [length-1] 提取的密钥创建另一个动态密钥,并将其分配给最后一个,全部在一行中。
length
是数组的第一个索引。但 [length-1]
是最后一个索引(它之前的那个)。 :last
是用于定义最后一个索引的别名(或者确切地说是第一个索引之前的那个)
length
然后使用 computed property name [length -1]
来获取最后一个元素。
可以通过 length
属性获取最后一项。由于数组计数从 0 开始,您可以通过引用 array.length - 1
项来选择最后一项
常量 arr = [1,2,3,4]; const last = arr[arr.length - 1];控制台.log(最后); // 4
另一种选择是使用新的 Array.prototype.at()
方法,该方法采用整数值并返回该索引处的项目。负整数从数组中的最后一项开始倒数,所以如果我们想要最后一项,我们可以传入 -1
常量 arr = [1,2,3,4];常量最后 = arr.at(-1);控制台.log(最后); // 4
另一种选择是使用新的 findLast
方法。您可以看到提案 here
常量 arr = [1,2,3,4]; const last = arr.findLast(x => true);控制台.log(最后); // 4
另一种选择是使用 Array.prototype.slice()
方法,它将数组的一部分的浅拷贝返回到新的数组对象中。
常量 arr = [1,2,3,4]; const last = arr.slice(-1)[0];控制台.log(最后); // 4
arr.findLast(() => true);
,因为您的版本不会“找到”像 0
或 ""
这样的虚假值,...
对于那些不怕重载 Array 原型的人(并且您不应该使用 enumeration masking):
Object.defineProperty( Array.prototype, "getLast", {
enumerable: false,
configurable: false,
writable: false,
value: function() {
return this[ this.length - 1 ];
}
} );
如果您来这里寻找它,这里有更多 Javascript 艺术
本着使用 reduceRight()
但更短的另一个答案的精神:
[3, 2, 1, 5].reduceRight(a => a);
它依赖于这样一个事实,即如果您不提供初始值,则会选择最后一个元素作为初始元素(查看文档 here)。由于回调只是不断返回初始值,因此最后一个元素将是最后返回的元素。
请注意,这应该被视为 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("."));
我通常使用underscorejs,你可以这样做
if (_.last(loc_array) === 'index.html'){
etc...
}
对我来说,这比 loc_array.slice(-1)[0]
更具语义
为了防止从原始数组中删除最后一项,您可以使用
Array.from(myArray).pop()
大部分浏览器都支持 (ES6)
In ECMAScript proposal Stage 1 建议添加将返回最后一个元素的数组属性:proposal-array-last。
句法:
arr.lastItem // get last item
arr.lastItem = 'value' // set last item
arr.lastIndex // get last index
您可以使用 polyfill。
提案作者:Keith Cirkel(chai 个作者)
我认为这应该可以正常工作。
var arr = [1, 2, 3];
var last_element = arr.reverse()[0];
只需反转数组并获取第一个元素。
编辑:如下所述,原始数组将被反转。为避免这种情况,您可以将代码更改为:
var arr = [1, 2, 3];
var last_element = arr.slice().reverse()[0];
这将创建原始数组的副本。
arr.slice().pop()
就个人而言,我会赞成 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]
无论你做什么,都不要只使用 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()
[1,3,4,5,"last"].slice().reverse()[0]
之前简单地复制数组
x = string.split('/'); return x[x.length-1]
,你可以做return x.split('/').pop()