获取数组中的最后一项

bal*_*der 1012 javascript arrays

这是我到目前为止的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);
Run Code Online (Sandbox Code Playgroud)

目前,它从URL中获取数组中倒数第二个项目.但是,我想检查数组中的最后一项是"index.html",如果是,请抓住第三项到最后一项.

Aar*_*run 1088

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

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

虽然,如果可能的话,你可能想考虑做这个服务器端:它会更干净,适用于没有JS的人.

  • 一些奇怪的人实际上在他们的浏览器中禁用了javascript.我知道这令人震惊. (133认同)
  • 我们是否都同意,如果一个用户禁用JavaScript,他们几乎已经搞砸了?不要为了支持奇怪的不可能场景而牺牲应用程序的设计和效率. (127认同)
  • "为没有JS的人工作" - 我...我不跟随. (118认同)
  • 我们是否都同意许多网络开发人员没有礼貌并且包括各种不受欢迎的膨胀脚本,例如跟踪,这是完全禁用随机不受信任网站上的JS的一个非常有效的理由?这并不像有些人想的那么不可能.如果你重视隐私,它实际上是一种理智的行为方式. (61认同)
  • 您是否认为99.9%的已禁用JS的"用户"实际上是从您的html中获取数据?或者开发人员"测试"你的网站是否与JS一起工作? (22认同)
  • 如果你只需要最后一项,你可以使用 Array.pop() (21认同)
  • Safari IOS、Chrome IOS 和 Samsung Internet 不支持 at() 方法 https://caniuse.com/mdn-javascript_builtins_string_at (20认同)
  • @BadriDerakhshan 这将不可避免地在返回之前从数组中删除最后一个元素,因此如果您只想检查数组的最后一个元素,则这不是一个选项。您还必须将其推回以将阵列恢复到以前的状态。 (16认同)
  • 那"为什么禁用JS"讨论真的属于这里? (8认同)
  • 我赞同Zelphir.页面随着javascript膨胀,这增加了加载时间,消耗的数据和一般的复杂性.除此之外,还有各种跟踪器在彼此之间共享数据,并且想要一般禁用javascript而不是阻止特定脚本是非常合理的.所述脚本还用于检查是否加载了其他(例如广告)脚本,然后给你一个大停车标志声称"我们需要广告来维持自己".我们也忘记的是,你永远不应该信任客户. (5认同)
  • 你不能像Python一样arr [-1]吗?slice只返回一个不是整数的数组 (5认同)
  • 不适用于*Safari* (5认同)
  • @BadriDerakhshan 的解决方案对于创建的数组是临时的情况非常有用。例如。而不是 `x = string.split('/'); return x[x.length-1]`,你可以做`return x.split('/').pop()` (3认同)

kri*_*tzi 897

不确定是否有缺点,但这似乎很简洁:

arr.slice(-1)[0] 
Run Code Online (Sandbox Code Playgroud)

要么

arr.slice(-1).pop()
Run Code Online (Sandbox Code Playgroud)

undefined如果数组为空,则两者都将返回.

  • 关注速度问题:@ user1941782做了微基准测试.slice()在新计算机上每秒可以运行大约1000万次.使用[len-1]的速度要快〜1000倍,但两者都是如此之快,以至于它们可能不会成为限制因素; 因此imho没有必要为使用slice()感到难过. (85认同)
  • @Badrush slice() 使用单个元素的副本创建新数组,并且 pop 仅修改该副本。原始阵列保持不变 (70认同)
  • 当你做一些像`windows.location.pathname.split('/')这样的事情时很好.tick(-1)[0]`避免需要一个中间变量*只是*所以你可以调用`len`在它上面,因为javascript不理解`[ - 1]`作为数组的最后一个元素,就像某些语言一样. (43认同)
  • `.pop()` 删除修改原始数组的最后一个元素。这与简单地检索该值不同。 (26认同)
  • 这可能效率稍低,具体取决于切片的写入方式.`slice()`创建一个新数组,在这种情况下只有最后一个元素,只是为了访问最后一个元素,所以你将有一些额外的内存分配(这需要一定的时间). (12认同)
  • @Govan 请参阅我的评论。你可以说这是每秒发生的次数过多。如果您需要更多,或者有可用的数组长度,请使用普通数组访问以获得最大性能“arr[arr.length-1]” (10认同)
  • 这样可以获得简洁,同时不会改变输入,就像`.pop()`那样. (7认同)
  • 无论如何,`window.location.pathname.split('/')。pop()`看起来更好 (5认同)
  • @mvmn 我很久以前做了一个基准测试,单个 2.4ghz 线程上的吞吐量约为每秒一到两百万个调用。所以除非你解决了无论如何都不应该在 JS 中解决的问题,否则它不会引人注目(与 arr[arr.length-1] 相比,iirc 的速度减慢了 50-100 倍) (5认同)
  • 使用解构也很好:`const [lastItem] = arr.slice(-1)` (2认同)
  • 这个方法很慢 (2认同)

小智 229

使用Array.pop:

var lastItem = anArray.pop();
Run Code Online (Sandbox Code Playgroud)

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

  • 这有效但它从数组中删除了该项,这不是OP所要求的. (219认同)
  • 我喜欢在一次性​​列表中使用它,我不想将它存储在变量中:`var last = path.split('/').pop();`很高兴这个答案就在这里! (37认同)
  • OP说"如果是这样的话,就抓住第三个而不是".如果你弹出,那么倒数第三个不再是倒数第三个..pop()确实"得到"了最后一项.我完全同意,尽管在答案本身中提到这种方法会修改数组会很好. (6认同)
  • `const lastItem = [...anArray].pop()` 将是避免突变的一种方法 (5认同)
  • 特别适合像这样的东西:`filename.split('.').pop()` (3认同)
  • 它不仅返回最后一个元素,而且将其删除! (2认同)

Ara*_*yan 156

@chaiguy发布的简短版本:

Array.prototype.last = function() {
    return this[this.length - 1];
}
Run Code Online (Sandbox Code Playgroud)

读取-1索引undefined已经返回.

编辑:

目前,偏好似乎是使用模块并避免触及原型或使用全局命名空间.

export function last(array) {
    return array[array.length - 1];
}
Run Code Online (Sandbox Code Playgroud)

  • 我非常喜欢这个解决方案,但是 - 关于@FarzadYZ评论 - http://www.w3schools.com/js/js_object_prototypes.asp声明:**只修改你自己的原型.永远不要修改标准JavaScript对象的原型.** (14认同)
  • 当使用像堆栈这样的数组时,我称它为'peek`类似于`pop` (11认同)
  • 如果实际使用它并不明显,这里有一个例子:`var lastItem = [3,2,1,5] .last();`.`lastItem`的值是'5`. (8认同)
  • @FarzadYZ - 任何自定义原型丢失的风险非常低.十多年来从未发生在我身上.此外,我反对它混淆其他开发人员,因为你可以轻松地在IDE中关注方法的来源,如果这还不够,你可以随时为自定义原型方法添加前缀(例如使用`_`)并确保绝不会混淆参与项目的任何人,除非他们没有被高级开发人员正确介绍给项目的人.我相信,经过多年,扩展原始原型是完全可以的.在团队工作时从未遇到过问题. (6认同)
  • 这个答案是正确的也很干净但是(!!!)使用Javascript的经验法则是"不要修改你不拥有的对象".这很危险,因为有很多原因,例如1.在你的团队中工作的其他开发人员可能会感到困惑,因为这种方法不是标准的2.随着库中的任何更新,甚至使用更低或更高的ECMAScript版本,它很容易丢失! (5认同)
  • 这怎么破坏了Array.forEach()?因为我尝试过,没有看到任何破坏... (4认同)
  • Imo 修改 `Array.prototype` 没有太大问题,但你应该使用 `Object.assign(Array.prototype, 'last', { value: function () { ... } });`。否则,该属性将是可枚举的。 (3认同)
  • **停止建议修改原型。**有一个[建议](https://github.com/keithamus/proposal-array-last)将此属性添加到javascript中,并且**由于此代码**它可以请勿在`.last`下添加[以避免“网络兼容性问题”](https://github.com/keithamus/proposal-array-last#other-considered-options)。你为什么要这么固执?“这从未发生在我身上”不是一个很好的借口。 (3认同)
  • @ bfred.it这些天偏好似乎是使用模块并避免触及原型或全局命名空间.这个答案是6岁,事情发生了一些变化.我会在答案中加上一个注释. (3认同)
  • 这应该是JS中数组的标准方法 (2认同)
  • 对于任何想知道的人来说,这会破坏 Array.forEach()。我仍然同意修改原型并不是最糟糕的事情,但这一点很糟糕。 (2认同)

Jos*_*ick 123

有两种选择:

var last = arr[arr.length - 1]
Run Code Online (Sandbox Code Playgroud)

要么

var last = arr.slice(-1)[0]
Run Code Online (Sandbox Code Playgroud)

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

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

  • `var last = arr [arr.length - 1]`是整个性能方面的最佳答案 (20认同)
  • 第一个选项的作用也非常明显。第二个没那么多 (11认同)
  • `arr.length-1`可能会快150-200倍但是当最慢的方法速度已经达到每秒数百万次操作时,我不认为性能是99.99%的主要问题(当切片时甚至更多)/pop允许你提取未保存在变量中的数组的最后一个元素,用于代码美容目的) (6认同)
  • 对于不熟悉js的程序员,arr.slice(-1)[0]尚不清楚。`arr [arr.length-1]`更清晰,更容易'猜测'程序员的想法:) (4认同)

Ran*_*ner 99

可以通过该length属性获取数组中的最后一项。由于数组计数从 0 开始,因此您可以通过引用该array.length - 1项目来选择最后一项

const arr = [1,2,3,4];
const last = arr[arr.length - 1];
console.log(last); // 4
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用新Array.prototype.at()方法,该方法采用整数值并返回该索引处的项目。负整数从数组中的最后一项开始倒数,因此如果我们想要最后一项,我们可以传入-1

const arr = [1,2,3,4];
const last = arr.at(-1);
console.log(last); // 4
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用新findLast方法。您可以在此处查看该提案(目前处于第 4 阶段)

const arr = [1,2,3,4];
const last = arr.findLast(x => true);
console.log(last); // 4
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用Array.prototype.slice()将数组的一部分的浅拷贝返回到新数组对象中的方法。

const arr = [1,2,3,4];
const last = arr.slice(-1)[0];
console.log(last); // 4
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 83

表现

今天 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) 在所有浏览器上最慢

在此处输入图片说明

细节

我测试了两种解决方案:

  • 可变:ABC

  • 不可变:DEFGHI, 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));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

Chrome 短字符串的示例结果

在此处输入图片说明


uce*_*fkh 65

以下是如何获得它对原始ARRAY没有影响

a = [1,2,5,6,1,874,98,"abc"];
a.length; //returns 8 elements
Run Code Online (Sandbox Code Playgroud)

如果使用pop(),它将修改您的数组

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

但你可以使用它,所以它对原始数组没有影响:

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 
Run Code Online (Sandbox Code Playgroud)

  • 你应该做slice(-1).pop(),否则你复制整个数组(你真的只需要复制最后一个元素). (6认同)

小智 50

"最干净"的ES6方式(IMO)将是:

const foo = [1,2,3,4];
const bar = [...foo].pop();
Run Code Online (Sandbox Code Playgroud)

这避免了变异foo,如.pop()将有,如果我们不使用的扩展操作.
那就是说,我也喜欢这个foo.slice(-1)[0]解决方案.

  • 请注意,此解决方案执行整个阵列的副本. (28认同)
  • 它和 `.slice(-1)[0]` 一样不可读,但速度更慢。不妨使用`.slice` (10认同)
  • 仅出于“干净”语法复制整个数组对我来说似乎很愚蠢。它甚至看起来都不那么好 (4认同)
  • 您还可以使用数组解构使其*更多* ES6 ;) /sf/answers/3253990701/ (2认同)

Pab*_*her 39

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

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

通过这种方式,您始终可以获得index.html之前的元素(假设您的数组已将孤立的index.html作为一个项目).注意:但是,您将丢失数组中的最后一个元素.

  • @skizeey然后更好地做loc_array.slice(-1).pop(),它只切掉最后一个元素. (15认同)
  • 它有点慢,但你可以做`loc_array.slice().pop()`. (5认同)

小智 37

我想如果你只想获得没有删除的元素,更简单的是使用这个:

arr.slice(-1)[0]
Run Code Online (Sandbox Code Playgroud)

顺便说一句......我没有检查性能,但我认为写起来更简单,更干净


小智 31

TL; 博士

const [y] = x.slice(-1)
Run Code Online (Sandbox Code Playgroud)

说明:根据 Mozilla 文档,
这种看起来很有趣的语法[y] = <array-or-an-object>实际上称为解构赋值

“解构赋值语法是一种 JavaScript 表达式,可以将数组中的值或对象中的属性解包为不同的变量”

在此处阅读更多相关信息

  • 绝对最好只使用“arr[arr.length - 1]”,因为它在大多数浏览器上更具可读性并且速度快了近一个数量级。 (2认同)

Moh*_*och 30

通过使用带负值的切片方法,可以获得数组的最后一项.

你可以阅读更多关于它在这里的底部.

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

使用pop()会改变你的数组,这并不总是一个好主意.

  • 如果性能是一个问题,请知道这个方法比`array [array.length - 1]慢得多``http://jsperf.com/get-last-item-from-array/13 (4认同)

akh*_*hid 28

在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]);
Run Code Online (Sandbox Code Playgroud)

  • 修改原始数组

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

console.log(arr.pop())
arr.push(5)
console.log(...arr.splice(-1));
Run Code Online (Sandbox Code Playgroud)

  • 通过创建自己的辅助方法

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

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

console.log(arr.last);
Run Code Online (Sandbox Code Playgroud)


ale*_*lex 27

你可以使用这种模式......

let [last] = arr.slice(-1);
Run Code Online (Sandbox Code Playgroud)

虽然读起来相当不错,但请记住它会创建一个新阵列,因此它的效率低于其他解决方案,但它几乎不会成为应用程序性能瓶颈.


Ric*_*all 27

您可以使用相对索引Array#at

const myArray = [1, 2, 3]

console.log(myArray.at(-1))
// => 3
Run Code Online (Sandbox Code Playgroud)

  • 截至 2021 年 3 月,它仍在提案中,不受任何浏览器支持 (5认同)
  • 现在支持 chrome92。https://www.chromestatus.com/feature/6123640410079232 (3认同)
  • 这是受支持的[自 Firefox 88(仅限 Nightly)和 Safari 14.1(使用 `jscOptions=--useAtMethod=true`)](//web.archive.org/web/20210606095430/https://kangax.github.io/ compat-table/esnext/#test-.at()_method_on_the_built-in_indexables)。“lastItem”提案可能会被撤回。 (2认同)

gau*_*its 22

ES6 对象解构是另一种方法。

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

您可以使用对象解构从 Array 中提取length属性。您使用[length-1]已提取的密钥创建另一个动态密钥,并将其分配给last,全部在一行中。

  • 谢谢,你能解释一下它到底有什么作用吗? (2认同)

use*_*616 21

如果想要一次性获得最后一个元素,他/她可以使用Array#splice():

lastElement = document.location.href.split('/').splice(-1,1);
Run Code Online (Sandbox Code Playgroud)

这里,不需要将split元素存储在数组中,然后到达最后一个元素.如果获得最后一个元素是唯一的目标,那么应该使用它.

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

  • 这不会返回数组中的最后一个元素,而不是最后一个元素本身吗? (5认同)
  • 这会修改数组.您可以使用slice(-1)而不是splice(-1)来保持原始数组不变.@AramKocharyan没有它,比较```["hi"]```vs```"hi"```. (5认同)
  • @tozazaburo是不是一回事? (2认同)

Jam*_*son 21

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

带有-1的Array.prototype.slice可用于创建仅包含原始Array的最后一项的新Array,然后可以使用Destructuring Assignment使用该新Array的第一项来创建变量。

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

console.log(lotteryNumbers.slice(-1));
// => [22]
console.log(lastNumber);
// => 22
Run Code Online (Sandbox Code Playgroud)

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

dev*_*os1 20

对于那些不怕重载数组原型的人(以及枚举屏蔽你不应该):

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

  • 它几乎不会破坏我的代码!为什么你这么想?如果有人想要重新定义undefined,那就让它们吧,尽管这是一个非常疯狂的事情.这就是JavaScript的强大功能.如果他们喜欢,他们也可以重新定义Array.getLast.此外,优秀的程序员使用Object.defineProperty来绕过枚举. (5认同)

Cee*_*man 19

jQuery解决了这个问题:

> $([1,2,3]).get(-1)
3
> $([]).get(-1)
undefined
Run Code Online (Sandbox Code Playgroud)

  • 但是,只有你已经使用过jQuery.加载一个完整的库来做一些支持数组的语言本身可以做的事情很疯狂. (19认同)
  • 在许多旧语言中,否定切片不是原生的,并且jQuery在大多数情况下节省了大量时间,因此这可能是开始使用它的一个很好的借口. (3认同)
  • 如果你不相信语言本身,那么使用jQuery就是你告诉自己的谎言.这实际上只不过是访问一个数组元素.有很多用例我赞同你,但这太基本了.同样,如果您已经在项目中使用了jQuery,那就完全没问题了.对于像访问数组的最后一个元素一样简单的东西,添加一个完整的,强大的库是不值得的. (3认同)
  • 另外:如果jQuery有一个方法`$ .defineVar = function(scope,name,value){scope [name] = value; 我仍然使用`var foo ='bar'`而不是`$ .defineVar(window,'foo','bar');`,无论jQuery投入多少文档.此外,jQuery有很好的文档记录,但Javascript也是如此.事实上,它甚至被指定.你真的不能得到更详细的信息. (2认同)

Pau*_*ker 19

这个问题已经存在了很长时间,所以我很惊讶没有人提到只是在最后一个元素之后重新开始pop().

arr.pop()arr[arr.length-1]和两者的效率完全一样高效arr.push().

因此,你可以逃脱:

---编辑[检查thePop是不是undefined在推之前] ---

let thePop = arr.pop()
thePop && arr.push(thePop)
Run Code Online (Sandbox Code Playgroud)

---结束编辑---

哪个可以减少到这个(相同的速度[编辑:但不安全!]):

arr.push(thePop = arr.pop())    //Unsafe if arr empty
Run Code Online (Sandbox Code Playgroud)

这是两倍慢arr[arr.length-1],但你不必满足于索引.这在任何一天都值得.

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

[方法] .............. [ETU 5 elems] ... [ETU 100万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 :)
Run Code Online (Sandbox Code Playgroud)

最后三个选项,特别[...arr].pop()是随着阵列大小的增加而变得非常糟糕.在没有我的机器内存限制的机器上,[...arr].pop()可能保持类似120:1的比例.不过,没有人喜欢资源匮乏.

  • 如果初始数组可以为空,则此方法将导致错误的结果,并且[[]`将变为[[undefined]`。您需要通过显式的`undefined`检查来保护向后推送,例如`myPop!== undefined &amp;&amp; arr.push(myPop)`。 (2认同)

Mai*_*rey 19

欧洲制造商协会 2022

通过 ECMA 2022,您将拥有一个新财产at()。要从数组或字符串中获取最后一个元素,可以使用at负索引-1[1,2,3].at(-1)https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at

如果您喜欢像 arr.last 那样更流畅地接收最后一项,您可以为数组对象定义自己的属性。

if (!Array.prototype.hasOwnProperty("last")) {
  Object.defineProperty(Array.prototype, "last", {
    get() {
      return this.at(-1);
    }
  });
}

a = [1,2,3];
console.log(a.last);
Run Code Online (Sandbox Code Playgroud)


nie*_*els 18

我通常使用underscorejs,你可以这样做

if (_.last(loc_array) === 'index.html'){
  etc...
}
Run Code Online (Sandbox Code Playgroud)

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

  • [`_.last`](https://lodash.com/docs/4.17.4#last)也适用于[Lodash](https://lodash.com/). (5认同)

Ale*_*ych 12

const lastElement = myArray[myArray.length - 1];
Run Code Online (Sandbox Code Playgroud)

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


Mic*_*ård 11

就个人而言,我会通过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]
Run Code Online (Sandbox Code Playgroud)


Zel*_*ius 11

我认为这应该可以正常工作。

var arr = [1, 2, 3];
var last_element = arr.reverse()[0];
Run Code Online (Sandbox Code Playgroud)

只需反转数组并获取第一个元素。

编辑:如下所述,原始数组将被反转。为避免这种情况,您可以将代码更改为:

var arr = [1, 2, 3];
var last_element = arr.slice().reverse()[0];
Run Code Online (Sandbox Code Playgroud)

这将创建原始数组的副本。

  • 这将改变原始数组 (2认同)
  • @Zellius 如果您要对数组进行切片,不妨只弹出最后一个元素。即`arr.slice().pop()` (2认同)

tri*_*587 10

您可以last()Array原型添加功能.

Array.prototype.last = function () {
    return this[this.length - 1];
};
Run Code Online (Sandbox Code Playgroud)

  • 请记住,这是一种非常沮丧的反模式. (6认同)
  • @ eko24ive简而言之,您正在修改在代码和脚本中存在的任何其他库中使用的全局对象,这很危险.此外,如果将来添加语言,您可能会将代码暴露给可能的破坏.过去有些图书馆做了这件事,非常遗憾.看看这个更多:/sf/ask/982392631/ (2认同)

Roh*_*dal 10

根据 ES2022,您可以使用Array.at()方法,该方法采用整数值并返回该索引处的项目。允许正整数和负整数。负整数从数组中的最后一项开始倒数。

演示:

const href = 'www.abc.com/main/index.html';
const loc_array = href.split('/');

// To access elements from an array we can use Array.at()
console.log(loc_array.at(-1)); // This will return item at last index.
Run Code Online (Sandbox Code Playgroud)


Иль*_*ько 9

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

句法:

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

arr.lastIndex // get last index
Run Code Online (Sandbox Code Playgroud)

您可以使用polyfill

笔者建议:基思Cirkel作者日期)


Mat*_*bon 8

您可以将新属性getter添加到原型中,Array以便可以通过所有实例访问它Array.

Getters允许您访问函数的返回值,就像它是属性的值一样.函数的返回值当然是array(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'
Run Code Online (Sandbox Code Playgroud)

在IE≤8中不起作用.


Luc*_*iva 8

如果您是来这里寻找的,这是更多Javascript艺术

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

[3, 2, 1, 5].reduceRight(a => a);
Run Code Online (Sandbox Code Playgroud)

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

请注意,这应该被视为Javascript艺术,绝不是我推荐的方式,主要是因为它运行时间为O(n),而且还因为它损害了可读性。

现在是认真的答案

我看到的最好方法(考虑到您希望它比更加简洁array[array.length - 1])是:

const last = a => a[a.length - 1];
Run Code Online (Sandbox Code Playgroud)

然后只需使用函数:

last([3, 2, 1, 5])
Run Code Online (Sandbox Code Playgroud)

如果您要处理上面使用的匿名数组[3, 2, 1, 5],则该函数实际上很有用,否则您将不得不实例化两次,这样效率低下且难看:

[3, 2, 1, 5][[3, 2, 1, 5].length - 1]
Run Code Online (Sandbox Code Playgroud)

啊。

例如,在这种情况下,您有一个匿名数组,必须定义一个变量,但是可以last()改用:

last("1.2.3".split("."));
Run Code Online (Sandbox Code Playgroud)


小智 8

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

Array.from(myArray).pop()
Run Code Online (Sandbox Code Playgroud)

几乎所有浏览器(ES6)都受支持


Pan*_*gic 7

编辑:

最近我想出了一个我现在认为最符合我需求的解决方案:

function w(anArray) {
  return {
    last() {
      return anArray [anArray.length - 1];
    };
  };
}
Run Code Online (Sandbox Code Playgroud)

有了上面的定义,我现在可以说:

let last = w ([1,2,3]).last();
console.log(last) ; // -> 3
Run Code Online (Sandbox Code Playgroud)

名称"w"代表"包装".您可以看到如何在"last()"之外轻松添加更多方法到此包装器.

我说"最适合我的需求",因为这允许我轻松地将任何其他类似的"辅助方法"添加到任何JavaScript内置类型.我想到的是Lisp的car()和cdr().


Eva*_*oll 7

使用 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(''); //=> ''
Run Code Online (Sandbox Code Playgroud)

它进一步规定init,,head列出来自(Learn You a Haskell)的怪物tail

列出怪物

  • 我不明白为什么这个答案有这么多反对票!Ramda 可以说比 Lodash 和 Underscore 都要好。它是纯粹的函数式和干净的,尽管如果有人不习惯函数式编程,可能会有点难以理解。这绝对是问题的一个很好的答案,尽管如果您唯一要做的就是获取数组中的最后一个元素,我仍然不建议使用库。 (3认同)

Sim*_*ver 7

无论做什么,都不要使用reverse()!!!

有几个答案提到了,reverse但没有提到reverse修改原始数组并且不(如在其他语言或框架中)返回副本的事实。

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"
Run Code Online (Sandbox Code Playgroud)

这可能是最糟糕的调试代码!

  • 如果您确实要反转阵列的**副本**,则可以立即使用散布运算符。例如`[... animals] .reverse()` (4认同)
  • 尽管如果您刚被解雇,这是一件很有趣的事情,但在离开之前,您可以将其放入代码库中: (2认同)

rya*_*e28 6

通常你不应该弄乱内置类型的原型,但这里有一个黑客/快捷方式:

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

这将允许所有数组对象都有一个last属性,您可以像这样使用它:

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

您不应该弄乱内置类型的原型,因为您永远不会在新的 ES 版本发布时使用,并且如果新版本使用与您的自定义属性相同的属性名称,则可能会发生各种中断。此外,这使得其他人很难遵循你的代码,尤其是对于加入团队的人来说。您可以将属性设置为您知道 ES 版本永远不会使用的东西,例如,listLastItem但这由开发人员自行决定。

或者您可以使用一个简单的方法:

const getLast = (list) => list[list.length - 1];
const last = getLast([1,2,3]); // returns 3
Run Code Online (Sandbox Code Playgroud)


Nen*_*vic 6

更新 - 2021 年 10 月 27 日(Chrome 97+)

提案现已Array.prototype.findLast进入第三阶段!

使用方法如下:

const array = [1, 2, 3, 4, 5];

const last_element = array.findLast((item) => true);
console.log(last_element);
Run Code Online (Sandbox Code Playgroud)

您可以在这篇 V8 博客文章中阅读更多内容。

您可以在“Chrome 新增功能”系列中找到更多内容。


Osm*_*rdi 5

我认为最简单,效率最低的方法是:

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案需要多O(n)个内存并花费O(n)时间.这真的不是理想的解决方案. (40认同)
  • 这是非常低效的.不要这样做. (11认同)
  • 不要这样做,这只是知识:) (2认同)
  • 为了获得最后一个元素而反转整个数组是非常低效的. (2认同)

Vla*_*den 5

使用 ES6/ES2015 扩展运算符 (...),您可以执行以下操作。

const data = [1, 2, 3, 4]
const [last] = [...data].reverse()
console.log(last)
Run Code Online (Sandbox Code Playgroud)

请注意,使用扩展运算符和反向操作我们没有改变原始数组,这是获取数组最后一个元素的纯粹方法。

  • 仅仅为了获取最后一个元素而反转整个数组是非常低效的。 (13认同)

Mic*_*tey 5

我建议创建辅助函数并每次重用它,你需要它.让我们的功能更加通用,不仅可以获得最后一项,还可以获得最后一项,以此类推.

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

用法很简单

var arr = [1,2,3,4,5];
last(arr);    //5
last(arr, 1); //4
last(arr, 9); //undefined
Run Code Online (Sandbox Code Playgroud)

现在,让我们解决原始问题

抓住第二个到最后一个项目表单数组.如果loc_array中的最后一项是"index.html",请抓住第三项到最后一项.

下一行完成了这项工作

last(loc_array, last(loc_array) === 'index.html' ? 2 : 1);
Run Code Online (Sandbox Code Playgroud)

所以,你需要重写

var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-2]))); 
Run Code Online (Sandbox Code Playgroud)

通过这种方式

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

或使用其他变量来提高可读性

var nodeName = last(loc_array, last(loc_array) === 'index.html' ? 2 : 1);
var newT = document.createTextNode(unescape(capWords(nodeName)));
Run Code Online (Sandbox Code Playgroud)


Dea*_*ano 5

使用 lodash _.last(array)获取数组的最后一个元素。

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


Ali*_*eza 5

怎么样像下面这样:

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

如果使用下划线Lodash,您可以使用_.last(),所以像:

if ('index.html' === _.last(array)) {  
   //do this 
} else { 
   //do that 
}
Run Code Online (Sandbox Code Playgroud)

或者您可以创建自己的最后一个函数:

const _last = arr => arr[arr.length - 1];
Run Code Online (Sandbox Code Playgroud)

并使用它:

if ('index.html' === _last(array)) {  
   //do this 
} else { 
   //do that 
}
Run Code Online (Sandbox Code Playgroud)


sid*_*thi 5

只是在这里放另一个选择。

loc_array.splice(-1)[0] === 'index.html'
Run Code Online (Sandbox Code Playgroud)

我发现上述方法更简洁,在线更简短。请随意尝试一下。

  • 从 [2012 年](/sf/answers/846953901/) 开始,`.slice(-1)` 答案已经被多次给出,其含义已被详细讨论(与此处不同)。请不要为了获得点赞而重复回答。 (2认同)