如何获得数组的第一个元素?


236

如何从这样的数组中获取第一个元素:

var ary = ['first', 'second', 'third', 'fourth', 'fifth'];

我尝试了这个:

alert($(ary).first());

但是它会回来[object Object]。所以我需要从数组中获取第一个元素,它应该是element 'first'


2
我强烈建议您按积极
程度

Answers:


338

像这样

alert(ary[0])

35
var a = []; a[7] = 'foo'; alert(a[0]);
Petah 2015年

72
假设数组中的第一个元素始终具有0的索引。您知道他们对假设的看法...
Andy

16
@Andy没有假设,因为OP的问题非常明确和具体。
John Hartsock 2015年

5
@Petah该代码没有错。它只是显示未定义,因为那是a [0]的值,它实际上是数组中的第一项。如果希望它显示foo,则应跳过所有未定义的值,但它不是数组中的第一项。
Michiel van der Blonk '16

5
@MichielvanderBlonk我只是指出一些用户可能不会想到的极端情况。
佩塔


92

以下是针对不同情况的一些方法。

在大多数情况下,访问第一个元素的最简单方法是

yourArray[0]

但这需要您检查[0]是否确实存在。

在现实世界中,您并不关心原始数组,也不想检查索引是否存在,而只想获取第一个元素或未定义的内联。

在这种情况下,可以使用shift()方法获取第一个元素,但是请谨慎使用此方法修改原始数组(删除第一项并返回它)。因此,阵列的长度减少了一个。此方法可用于仅需要获取第一个元素但不关心原始数组的内联情况。

yourArray.shift()

要知道的重要一点是,如果您的数组以[0]索引开头,则以上两项只是一个选择。

在某些情况下,第一个元素已被删除,例如,delete yourArray [0]使数组上留有“空洞”。现在[0]处的元素只是未定义,但您想获取第一个“现有”元素。我已经在现实世界中看到了许多案例。

因此,假设我们不了解数组和第一个键(或者我们知道有孔),我们仍然可以获得第一个元素。

您可以使用find()获取第一个元素。

find()的优点是它的效率,因为当达到第一个满足条件的值时,它会退出循环(有关更多信息,请参见下文)。(您也可以自定义条件以排除null或其他空值)

var firstItem = yourArray.find(x=>x!==undefined);

我还想在此处包括filter()作为选项,以便首先“修复”副本中的数组,然后获取第一个元素,同时保持原始数组不变(未修改)。

在此处包括filter()的另一个原因是它存在于find()之前,并且许多程序员已经在使用它(这是ES5,而find()是ES6)。

var firstItem = yourArray.filter(x => typeof x!==undefined).shift();

警告filter()并不是真正有效的方法(filter()运行于所有元素)并创建另一个数组。可以在小型阵列上使用,因为对性能的影响很小,例如,更接近于使用forEach。

(我看到有人建议使用for ... in循环来获取第一个元素,但是我建议反对使用...... in不应在索引顺序很重要的Array上进行迭代,因为它不会顺便说一下,forEach不能解决很多建议的问题,因为您不能破坏它,它会贯穿所有元素,因此最好还是使用简单的for循环并通过检查键/值

find()和filter()都保证元素的顺序,因此如上所述可以安全使用。


1
为什么不随后取消数组移位,例如:var element = yourArray.shift(); yourArray.unshift(element);
格雷格

9
因为这是非常低效和不好的事情。您可以以非常有效的方式获得第一个元素。shift和unshift都进行一些检查并遍历整个数组以完成任务,因为在开头删除或添加新元素时,所有其他索引都应移动。就像您有一辆载满人的公共汽车,当后排座位上的某人想要下车时,您通过前门排空公共汽车,然后要求他们再次上车。
Selay

1
@Selay取决于解释器的特定内部。
Michiel van der Blonk '16

@Michiel van der Blonk您能否让我知道您所说的是哪个口译员。我很感兴趣。我所知道的所有实现都使用循环和复制。这就是JavaScript数组的工作方式。您不能简单地轻松删除第一个元素,因为剩下的数组现在从1开始(位置0的元素已删除),您需要对其进行修复。无论您采用哪种内部实现,都无法制造魔术。
Selay

如果使用yourArray.map(n=>n).shift()它,将返回第一项而不修改原始项...不知道这是否是最好的方法,但是如果您将数组与.map()。filter()。some()。shift()链接起来,就可以了..否则我会用yourArray[0]
Michael J. Zoidl '17

53

如果第一个元素已删除,则索引0的元素可能不存在:

let a = ['a', 'b', 'c'];
delete a[0];

for (let i in a) {
  console.log(i + ' ' + a[i]);
}

没有jQuery的第一个更好的方法:

function first(p) {
  for (let i in p) return p[i];
}

console.log( first(['a', 'b', 'c']) );


1
a.entries()[0]应该做到这一点:)
Edson Medina

1
那是因为您不应该对数组使用这种枚举,因为它是在枚举对象而不是数组成员。改用传统的for循环索引。
Oskar Duveborn

类似的ES6方法(也不依赖于数字索引)在这里:stackoverflow.com/a/56115413/7910454
leonheess

51

使用ES6解构

let [first] = [1,2,3];

与...相同

let first = [1,2,3][0];

如果数组以[0]索引开头,则可能需要添加“销毁”选项。
leonheess

46

如果您想保持可读性,可以随时向中添加第一个函数Array.protoype

Array.prototype.first = function () {
    return this[0];
};

然后,您可以轻松检索第一个元素:

[1, 2, 3].first();
> 1

14
出于充分的原因,以任何方式修改基类的原型被认为是非常不好的做法。
德米特里·马特维耶夫

11
真傻,打字.first()比做起来[0]好吗?
jonschlinkert

10
@jonschlinkert某些语言的索引以开头1first在这种情况下是明确的。
Bartek Banachewicz 2014年

6
[] .first()返回什么?
Rhyous 2015年

1
在我的测试中,它返回未定义。我试图确定是否喜欢返回未定义的内容。
Rhyous 2015年

33

您可以使用find()

let first = array.find(Boolean);

或者如果您想要第一个元素,即使它是虚假的

let first = array.find(e => true);

加倍努力:

如果您关心可读性,但又不想依赖于数字发生率,则可以通过定义它来添加first()-function Array.protoypeObject​.define​Property()从而减轻直接修改内置Array对象原型的陷阱(在此进行说明)。

性能相当不错(find()在第一个元素之后停止),但是它并不完美或无法普遍访问(仅适用于ES6)。有关更多背景信息,请阅读@Selays答案

Object.defineProperty(Array.prototype, 'first', {
  value() {
    return this.find(e => true);     // or this.find(Boolean)
  }
});

然后,可以检索第一个元素:

let array = ['a', 'b', 'c'];
array.first();

> 'a'

摘录以查看实际效果:

Object.defineProperty(Array.prototype, 'first', {
  value() {
    return this.find(Boolean);
  }
});

console.log( ['a', 'b', 'c'].first() );


3
这是最好,最新的答案。我本来打算在这里发布相同内容,但在看到您的内容后:)
Kostanos

如果在将来的语言版本中他们将添加find()会发生什么?:-)上面的代码片段不会破坏它吗?
博格丹

@Bogdan您何时添加它们find()是什么意思?find()长期以来一直是该语言的一部分。这就是上面的代码片段起作用的原因。
leonheess

哦 抱歉,有点累了,我第一次睡的还没睡。
博格丹

@Bogdan它仍然可以很好地工作,但是会覆盖潜在的未来first()语言方法
-leonheess

18

如果不能保证从索引零开始填充数组,则可以使用Array.prototype.find()

var elements = []
elements[1] = 'foo'
elements[2] = 'bar'

var first = function(element) { return !!element }    
var gotcha = elements.find(first)

console.log(a[0]) // undefined
console.log(gotcha) // 'foo'

3
确实应该对此进行更高的投票。我看到的这是最简洁的解决方案,它使用普通js并处理稀疏数组。
Dominic P


1
我建议不要使用,!!element因为它会跳过虚假的值。我建议find()以这种方式使用:sparse.find((_, index, array) => index in array);
维克多·韦林

在这里不消除虚假值的类似方法:stackoverflow.com/a/56115413/7910454
leonheess

13
array.find(e => !!e);  // return the first element 

因为“ find”返回与过滤器!!e匹配的第一个元素&& 与任何元素匹配。

注意: 这只能当第一个元素是不是“Falsy”: ,nullfalseNaN,,""0undefined


1
Abdennour可以为他人澄清您的情况是否符合任何真实元素,即<code> const example = [null,NaN,0,未定义,{},3,'a'];const firstTruthyElement = example.find(e => !! e); //分配第5个元素,第一个非伪造元素:{} </ code>
PDA

感谢@PDA赶上来。顺便说一句,空字符串也被认为是虚假的
-Abdennour TOUMI

3
这很棒,并且在TypeScript中也很好用。简化为array.find(() => true);呢?这也使您能够做到[false].find(() => true)
西蒙·沃塔

@SimonWarta当然.find(value => true)可以按预期运行……但是说实话,如果您想要更简洁的代码并保持打字稿中的键入内容,请使用destructuring
Flavien Volken '18

在没有忽略虚假元素的陷阱的情况下,以类似方式查看此答案
leonheess



7

我知道从其他语言到JavaScript的人们都在寻找类似的东西head()first()获取数组的第一个元素,但是如何做到这一点呢?

假设您有以下数组:

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

在JavaScript中,您可以简单地执行以下操作:

const first = arr[0];

或更整洁的新方法是:

const [first] = arr;

但是你也可以简单地写一个像... 的函数

function first(arr) {
   if(!Array.isArray(arr)) return;
   return arr[0];
}

如果使用下划线,则可以使用功能列表执行与您期望的功能相同的操作:

_.first 

_.head

_.take

6

与数组一起使用的方法,也与对象一起使用(请注意,对象没有确定的顺序!)。

我最喜欢此方法,因为未修改原始数组。

// In case of array
var arr = [];
arr[3] = 'first';
arr[7] = 'last';
var firstElement;
for(var i in arr){
    firstElement = arr[i];
    break;
}
console.log(firstElement);  // "first"

// In case of object
var obj = {
    first: 'first',
    last: 'last',
};

var firstElement;

for(var i in obj){
    firstElement = obj[i];
    break;
}

console.log(firstElement) // First;


4

对于那些只关心真实元素的人

ary.find(Boolean);

4

使用过滤器查找数组中的第一个元素:

在打字稿中:

function first<T>(arr: T[], filter: (v: T) => boolean): T {
    let result: T;
    return arr.some(v => { result = v; return filter(v); }) ? result : undefined;
}

用简单的javascript:

function first(arr, filter) {
    var result;
    return arr.some(function (v) { result = v; return filter(v); }) ? result : undefined;
}

同样,indexOf:

在打字稿中:

function indexOf<T>(arr: T[], filter: (v: T) => boolean): number {
    let result: number;
    return arr.some((v, i) => { result = i; return filter(v); }) ? result : undefined;
}

用简单的javascript:

function indexOf(arr, filter) {
    var result;
    return arr.some(function (v, i) { result = i; return filter(v); }) ? result : undefined;
}

3

当存在多个匹配项时,JQuery的.first()用于获取与给jquery的css选择器匹配的第一个DOM元素。

您不需要jQuery即可操纵javascript数组。


3

为什么不考虑阵列可能为空的时间?

var ary = ['first', 'second', 'third', 'fourth', 'fifth'];
first = (array) => array.length ? array[0] : 'no items';
first(ary)
// output: first

var ary = [];
first(ary)
// output: no items

3

只需使用 ary.slice(0,1).pop();

var ary = ['first', 'second', 'third', 'fourth', 'fifth'];

console.log("1º "+ary.slice(0,1).pop());
console.log("2º "+ary.slice(0,2).pop());
console.log("3º "+ary.slice(0,3).pop());
console.log("4º "+ary.slice(0,4).pop());
console.log("5º "+ary.slice(0,5).pop());
console.log("Last "+ary.slice(-1).pop());

array.slice(START,END).pop();


为什么这样做而不是ary[0]呢?
nathanfranke


1

用它来分割javascript中的字符。

var str = "boy, girl, dog, cat";
var arr = str.split(",");
var fst = arr.splice(0,1).join("");
var rest = arr.join(",");

1

当数组索引从零开始时,上述示例可以很好地工作。thomax的答案不依赖于从零开始的索引,而是依赖于Array.prototype.find我没有访问权限的索引。以下使用jQuery $ .each的解决方案在我的情况下效果很好。

let haystack = {100: 'first', 150: 'second'},
    found = null;

$.each(haystack, function( index, value ) {
    found = value;  // Save the first array element for later.
    return false;  // Immediately stop the $.each loop after the first array element.
});

console.log(found); // Prints 'first'.

1

您可以通过lodash _.head轻松完成。

var arr = ['first', 'second', 'third', 'fourth', 'fifth'];
console.log(_.head(arr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>


2
arr[0]正如您在这里看到的,它的字面意思就是这样做的原因,这就是为什么我强烈不鼓励使用lodash之类的巨大库来完成这么小的任务。
leonheess

1

var ary = ['first', 'second', 'third', 'fourth', 'fifth'];
alert(Object.values(ary)[0]);


这是香草JS,没有了jQuery,没有库,没有什么..:如果数组索引不从零开始P..it将工作,它会工作,如果世界上还没有结束....
天璇马雷

0

@NicoLwk您应该删除带有拼接的元素,这将使数组移回。所以:

var a=['a','b','c'];
a.splice(0,1);
for(var i in a){console.log(i+' '+a[i]);}

2
该答案是对上述(NicoLwks)答案的评论,应删除
Lino,

0

声明原型以获取第一个数组元素为:

Array.prototype.first = function () {
   return this[0];
};

然后将其用作:

var array = [0, 1, 2, 3];
var first = array.first();
var _first = [0, 1, 2, 3].first();

或简单地(:

first = array[0];

0

如果要将视图函数链接到数组,例如

array.map(i => i+1).filter(i => i > 3)

并且想要这些功能之后的第一个元素,您可以简单地添加一个.shift()它不会修改原始元素,这array是一种更好的方式array.map(i => i+1).filter(=> i > 3)[0]

如果您想要数组的第一个元素而不修改原始元素,则可以使用array[0]array.map(n=>n).shift()(在没有地图的情况下,您将修改原始元素。在这种情况下,我建议使用该..[0]版本。


0
var ary = ['first', 'second', 'third', 'fourth', 'fifth'];

console.log(Object.keys(ary)[0]);

制作任何Object数组(req),然后简单Object.keys(req)[0]地选择Object数组中的第一个键。


2
尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
DimaSan '17

0

@thomax的答案非常好,但是如果数组中的第一个元素为false或false-y(0,空字符串等),它将失败。对于未定义的内容,最好只返回true:

const arr = [];
arr[1] = '';
arr[2] = 'foo';

const first = arr.find((v) => { return (typeof v !== 'undefined'); });
console.log(first); // ''

-1

ES6简单:

let a = []
a[7] = 'A'
a[10] = 'B'

let firstValue = a.find(v => v)
let firstIndex = a.findIndex(v => v)

1
否……它将返回第一个定义的值。如果第一个为null,undefined,false,0或空字符串,则将跳过该第一个。试试:[false, 0, null, undefined, '', 'last'].find(v => v)
Flavien Volken '18

好一点,我的解决方案仅适用于具有定义值的数组。
JanJarčík18年

1
那么为什么要使用该值进行过滤?a.find(value => true)不会忽略任何值。不过,我不建议您使用find获得第一项。
Flavien Volken '18

1
@ MiXT4PE返回true(就像您的回答一样)是可以的,因为它将在第一个元素处停止,在这里它返回元素本身……如果认为该元素为假,它​​将继续下去
Flavien Volken '19

1
使用“ find”的@ MiXT4PE较慢,更复杂且较不美观。我还怀疑是否有任何智能编辑器能够重构此操作。使用解构会更高效,通过语言可以理解(以便您可以重构),可以通过编译器(对于TS)可以理解类型,并且很有可能是最快的解决方案。
Flavien Volken '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.