在JavaScript中循环遍历数组

3986
在Java中,您可以使用for循环遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
    // Do something
}

我能在JavaScript中做同样的事情吗?


7
我有点困惑,使用增强for循环来访问对象是可以的吗?而用顺序循环来填充一个对象呢?这样做正确吗? - Mark Szymanski
54
不,这很简单,数组对象有数字索引,所以你想按照数字顺序迭代这些索引,一个连续的循环可以保证这一点,增强型的 for-in 循环枚举对象属性时没有特定的顺序,并且也枚举继承的属性...对于迭代数组,始终建议使用连续的循环。 - Christian C. Salvadó
7
相关 - https://dev59.com/mG435IYBdhLWcg3wjwzS - jondavidjohn
9
这里有一个循环遍历数组的解决方案的基准测试:http://jsben.ch/#/Q9oD5 - EscapeNetscape
13
@CMS 不,实际上并不简单。在其他所有语言中都很简单。但在JS中却非常复杂,因为你需要使用inof,它们有不同的用法。此外,你还需要使用forEach和丑陋而烦人的基于索引的循环方式。其他现代语言循环集合都很容易和直观,没有任何意外或困惑。JS也可以做到,但它并没有。 - jpmc26
显示剩余5条评论
46个回答

5148

三种主要选项:

  1. for (var i = 0; i < xs.length; i++) { console.log(xs[i]); }
  2. xs.forEach((x, i) => console.log(x));
  3. for (const x of xs) { console.log(x); }

详细的例子如下。


1. 顺序for循环:

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

优点

  • 适用于任何环境
  • 可以使用breakcontinue流程控制语句

缺点

  • 过于冗长
  • 命令式的
  • 容易出现差一错误(有时也称为栅栏帖错误

2. Array.prototype.forEach:

ES5规范引入了许多有益的数组方法之一是Array.prototype.forEach,它为我们提供了一种简洁的迭代数组的方式:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

在撰写本文时,ES5规范已经发布了将近十年的时间(2009年12月),几乎所有现代桌面、服务器和移动环境中的引擎都已经实现了它,因此可以放心使用。

而且通过使用ES6箭头函数语法,代码更加简洁:

array.forEach(item => console.log(item));

箭头函数也被广泛实现,除非你计划支持古老的平台(例如Internet Explorer 11);否则你也可以安全使用。

优点

  • 非常短小精悍。
  • 声明式

缺点

  • 无法使用break/continue

通常情况下,您可以通过在迭代之前过滤数组元素来替换需要从命令式循环中break出来的需求,例如:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

请记住,如果您正在迭代一个数组以构建另一个数组,则应该使用map。我已经看到了这种反模式很多次。

反模式:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

map的正确使用案例:

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

如果你想将数组减少到一个值,例如,你想对一组数字求和,那么你应该使用reduce方法。

反面例子:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

适当使用 reduce

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. ES6 for-of 语句:

ES6 标准引入了可迭代对象的概念,并定义了一种新的用于遍历数据的结构,即 for...of 语句。

此语句适用于任何类型的可迭代对象,也适用于生成器(任何具有 \[Symbol.iterator\] 属性的对象)。

在 ES6 中,数组对象是内置的可迭代对象,因此您可以在其上使用此语句:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

优点

  • 可以迭代大量的对象。
  • 可以使用正常的流程控制语句(break / continue)。
  • 用于迭代串行异步值非常有用。

缺点

不要使用for...in

@zipcodeman建议使用for...in语句,但是对于迭代数组,应该避免使用for-in语句,该语句用于枚举对象属性。

它不应该用于类似数组的对象,因为:

  • 迭代顺序不能保证; 数组索引可能不按数字顺序访问。
  • 还会枚举继承的属性。
第二点是它可能会给你带来很多问题,比如,如果你扩展了Array.prototype对象以包含一个方法,那么该属性也将被枚举。
例如:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

上面的代码将会在控制台输出 "a", "b", "c" 和 "foo!"。
如果你使用一些依赖于原生原型扩展的库(比如 MooTools),这可能会成为一个问题。
正如我之前所说,for-in 语句用于枚举对象属性,例如:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

在上面的例子中,hasOwnProperty方法允许您仅枚举自有属性。也就是说,仅枚举对象实际具有的属性,而不包括继承的属性。
我建议您阅读以下文章:

12
我知道这个答案早于async和Promises,但我觉得在任何关于现代JavaScript的对话中提到它都是值得一提的:“forEach不会等待Promise。当你使用Promise(或async函数)作为forEach回调时,请确保你了解后果。” (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) - bmaupin
7
ES6中for-of的缺点:无法获取当前索引。 - Vic
1
@Vic 你可以这样做,但这并不是一件简单的事情。 - Alvaro Carvalho
2
参考以下代码,可以在循环中获取当前索引。我个人认为这非常简单明了。for (const [i, x] of yourArray.entries()) { ... } - Scotty Jamison
2
对于那些看到这个答案并想知道他们应该选择forEach()还是for-of的人,我建议使用for-of。for-of是较新的循环语法,完全取代了使用forEach的需要。for-of没有任何forEach所没有的功能,但反过来则不一定成立。 - Scotty Jamison
显示剩余8条评论

1201

是的,假设你的实现包括ECMAScript 2015(“Harmony”版本)中引入的for...of功能......这在今天是非常安全的假设。

它的工作原理如下:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

更好的是,自从 ECMAScript 2015 提供了块级作用域变量后:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

在每次迭代中,变量s都不同,但只要不在那里修改它,仍然可以在循环体内声明为const

关于稀疏数组的说明:JavaScript中的数组可能实际上并不存储与其length所报告的项数相同的项;该数字仅比存储值的最高索引大1。如果数组保存的元素少于其长度所示,则称其为稀疏。例如,拥有仅在索引3、12和247处具有项目的数组是完全合法的;这样一个数组的length为248,尽管它实际上只存储了3个值。如果您尝试访问任何其他索引处的项,则该数组将显示为具有undefined值,但该数组仍然与实际上具有存储undefined值的数组不同。您可以以多种方式看到此差异,例如在Node REPL中显示数组的方式:

> a              // array with only one item, at index 12
[ <12 empty items>, 1 ]
> a[0]           // appears to have undefined at index 0
undefined
> a[0]=undefined // but if we put an actual undefined there
undefined
> a              // it now looks like this
[ undefined, <11 empty items>, 1 ]

当你想要“循环遍历”一个数组时,你需要回答一个问题:你想要遍历长度所指示的完整范围并处理任何缺失元素的undefined,还是只想处理实际存在的元素?这两种方法都有很多应用;它只取决于你使用数组的方式。
如果你使用for..of迭代一个数组,循环体会被执行length次,并且循环控制变量会被设置为undefined,对于数组中实际不存在的项。根据你的“做某事”的代码的细节,那种行为可能是你想要的,但如果不是,你应该使用不同的方法。
当然,一些开发者无论如何都别无选择,因为由于某种原因,他们正在针对尚未支持for...of的JavaScript版本进行开发。
只要您的JavaScript实现符合ECMAScript规范的旧版(例如Internet Explorer 9之前的版本就不行),您就可以使用Array#forEach迭代器方法而不是循环。在这种情况下,您需要传递一个函数,以便在数组中的每个项上调用该函数:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

如果您的实现支持ES6 +,当然可以使用箭头函数:

myStringArray.forEach( s => { 
     // ... do something with s ...
} );

for...of不同,.forEach仅调用实际存在于数组中的元素的函数。如果传递具有三个元素和长度为248的假想数组,则它仅调用函数三次,而不是248次。如果这是您想要处理稀疏数组的方式,则即使您的解释器支持for...of.forEach也可能是一种方法。

最后一个选项,在所有JavaScript版本中都有效,是显式计数循环。您只需从0计数到长度减1,并将计数器用作索引即可。基本循环如下所示:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

这种方法的一个优点是您可以选择如何处理稀疏数组。上面的代码将在循环体内完整地运行length次,对于任何缺失的元素,s会被设置为undefined,就像使用for..of一样;如果您想要处理稀疏数组中实际存在的元素,就像使用.forEach一样,您可以在索引上添加一个简单的in测试:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

根据您的实现优化,将长度值分配给本地变量(而不是在循环条件中包括完整的myStringArray.length表达式)可以显著提高性能,因为它可以跳过每次查找属性。您可能会在循环初始化子句中看到长度缓存,如下所示:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

明确的计数循环还意味着您可以访问每个值的索引(如果需要)。该索引也作为额外参数传递给您传递给forEach的函数,因此您也可以通过这种方式访问它:
myStringArray.forEach( (s,i) => {
   // ... do something with s and i ...
});

for...of不能给你每个对象关联的索引,但只要你迭代的对象实际上是Array的一个实例(而不是其他可迭代类型for..of可以使用的),你可以使用Array#entries方法将其更改为[index,item]对的数组,然后迭代它:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

其他人提到的for...in语法是用于循环遍历对象属性的;由于JavaScript中的数组只是一个具有数值属性名称(以及自动更新的length属性)的对象,因此理论上可以使用它来循环遍历数组。但问题在于它不仅限于数值属性值(请记住,即使方法实际上只是其值为闭包的属性),而且不能保证按数值顺序迭代。因此,for...in语法不应用于循环遍历数组。

24
请注意,一些解释器(例如V8)会在代码调用足够多次并检测到循环时未修改数组长度时自动缓存数组的长度。 尽管缓存长度仍然不错,但当您的代码被调用足够多次以实际产生差异时,它可能无法提供速度提升。 - Phrogz

453
你可以使用map,这是一种函数式编程技术,也适用于其他语言,例如PythonHaskell
[1,2,3,4].map( function(item) {
     alert(item);
})

通用语法如下:

array.map(func)

通常情况下,func 接收一个参数,即数组的每个元素。但在 JavaScript 中,它还可以接收第二个参数,即元素的索引,以及第三个参数,即该数组本身。

array.map 的返回值是另一个数组,所以您可以像这样使用它:

var x = [1,2,3,4].map( function(item) {return item * 10;});

现在x是[10,20,30,40]

您不必内联编写该函数,它可以是一个单独的函数。

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

这在某种程度上等价于:

 for (item in my_list) {item_processor(item);}

除非你不获得new_list


103
这个例子最好使用Array.forEach来实现。map是用于生成新数组的。 - harto
21
@hasen,“Array.prototype.map”方法是ECMAScript第5版标准的一部分,但并不是所有实现都可用(例如IE缺少此功能)。 此外,对于遍历数组,我认为“Array.prototype.forEach”方法在语义上更加正确。请不要建议使用“for-in”语句,请参见我的答案以获取更多详细信息 :) - Christian C. Salvadó

142

for (const s of myStringArray) {

(直接回答你的问题:现在可以了!)

其他回答都是正确的,但它们没有提到(截至本文写作时)ECMAScript 6 2015将带来一种新的迭代机制,即for..of循环。

这个新语法是JavaScript中迭代数组最优雅的方式(只要不需要迭代索引)。

它目前支持Firefox 13+和Chrome 37+,并且它在其他浏览器上不能自动工作(请参见下面的浏览器兼容性)。幸运的是,我们有JavaScript编译器(例如Babel),可以让我们使用未来的特性。

它还适用于Node.js(我在版本0.12.0上进行了测试)。

迭代一个数组

// You could also use "let" or "const" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
   console.log(letter);
}

迭代对象数组

const band = [
  {firstName : 'John', lastName: 'Lennon'},
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(const member of band){
  console.log(member.firstName + ' ' + member.lastName);
}

迭代生成器:

(示例摘自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)

function* fibonacci() { // A generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (const n of fibonacci()) {
  console.log(n);
  // Truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

兼容性表格: http://kangax.github.io/compat-table/es6/#test-for..of_loops

规范: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}


132

在JavaScript中,不建议使用for-in循环遍历数组,而是最好使用for循环,例如:

for(var i=0, len=myArray.length; i < len; i++){}

它也经过了优化("缓存"数组长度)。如果您想了解更多,请阅读我在这个主题上的文章


101

6种不同的数组遍历方法

您可以通过许多不同的方法遍历数组。我已经按照我最喜欢的6种方法从上到下排序。

1. 使用JavaScript for循环

当只需要简单地遍历数组时,for循环是我的首选。

let array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}

2. 使用forEach循环

forEach循环是一种现代的遍历数组的方式。此外,它还提供了更多的灵活性和对数组和元素的控制。

let array = [1, 2, 3, 4, 5];
array.forEach((element) => {
  console.log(element);
});

3. 使用 for...of

for...of 循环直接让你访问数组元素。

let array = [1, 2, 3, 4, 5];
for (let element of array) {
  console.log(element);
}

4. 使用 for...in 循环

for...in 循环可以提供一个键,通过该键可以访问数组元素。

let array = [1, 2, 3, 4, 5];
for(let index in array){
  console.log(array[index]);
}

5. 使用while循环

while循环也可以用来遍历数组。

let array = [1, 2, 3, 4, 5];
let length = array.length;
while(length > 0){
  console.log(array[array.length - length]);
  length--;
}

6. 使用 do...while 循环

同样地,我使用 do...while 循环

let array = [1, 2, 3, 4, 5];
let length = array.length;
do {
  console.log(array[array.length - length]);
  length--;
}
while (length > 0)


94

现在,Opera、Safari、Firefox和Chrome共享一组增强的数组方法以优化许多常见的循环操作。

您可能不需要使用全部这些方法,但它们非常有用,如果每个浏览器都支持它们就更好了。

Mozilla Labs发布了它们和 WebKit 都在使用的算法,因此您可以自己添加它们。

filter 返回满足某些条件或测试的项目数组。

every 如果每个数组成员都通过了测试,则返回true。

some 如果任何一个成员通过了测试,则返回true。

forEach 对每个数组成员运行一个函数并且不返回任何值。

map 类似于forEach,但它返回一个结果数组,该数组包含每个元素操作的结果。

这些方法都采用函数作为它们的第一个参数,并具有可选的第二个参数,该参数是一个对象,您希望在函数循环遍历数组成员时对其施加作用域。

在您需要它之前请忽略它。

indexOflastIndexOf 找到与其参数完全匹配的第一个或最后一个元素的适当位置。

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();

83

简介

自我大学以来,我就会使用Java、JavaScript、Pascal、ABAP、PHP、Progress 4GL、C/C++等编程语言,可能还有其他一些语言现在想不起来了。

虽然它们都有自己的语言特点,但是这些语言共享许多相同的基本概念,如过程/函数、IF语句、FOR循环和WHILE循环。


传统的for循环

传统的for循环有三个组成部分:

  1. 初始化:在第一次执行循环块之前执行
  2. 条件:每次在执行循环块之前检查条件,并在条件为假时退出循环
  3. 后处理:在执行循环块之后每次执行

这三个组成部分由;符号分隔。每个组成部分的内容都是可选的,这意味着以下是可能的最简单的for循环:

for (;;) {
    // Do stuff
}

当然,在那个for循环中,你需要包含一个if(condition === true) { break; } 或者 if(condition === true) { return; }来使其停止运行。
通常,初始化用于声明索引,条件用于将该索引与最小或最大值进行比较,并且afterthought用于递增索引:
for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

使用传统的for循环来遍历数组

遍历数组的传统方式如下:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

或者,如果你喜欢反向循环,可以这样做:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

然而,有许多可能的变化,例如这个:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

...或者这个...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

...或者这一个:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

无论哪种方式最好,这主要是个人口味和你正在实现的具体用例的问题。请注意,所有浏览器都支持每种变体,包括非常旧的浏览器!

使用while循环

while循环是for循环的一种替代方案。要遍历数组,你可以这样做:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

与传统的for循环一样,即使是最古老的浏览器也支持while循环。

此外,请注意,每个while循环都可以重写为for循环。例如,此处的while循环的行为与此for循环相同:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...infor...of

在 JavaScript 中,你也可以这样做:

for (i in myArray) {
    console.log(myArray[i]);
}

然而,需要小心使用它,因为它在某些情况下与传统的for循环不同,并且需要考虑潜在的副作用。有关更多详细信息,请参见为什么使用"for...in"来迭代数组是一个坏主意?

作为for...in的替代方案,现在还有for...of。以下示例显示了for...of循环和for...in循环之间的区别:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

另外,您需要考虑到Internet Explorer的任何版本都不支持for...ofEdge 12+支持),而且for...in至少需要Internet Explorer 10。


Array.prototype.forEach()

for循环的替代方法是Array.prototype.forEach(),它使用以下语法:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach()被所有现代浏览器支持,包括Internet Explorer 9及更高版本。


最后,许多实用程序库也有自己的foreach变体。据我所知,最流行的三个是这些:

jQuery.each(),在jQuery中:

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(),在Underscore.js中:

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), 在 Lodash 中:

_.forEach(myArray, function(value, key) {
    console.log(value);
});

70

使用while循环...

var i = 0, item, items = ['one', 'two', 'three'];
while(item = items[i++]){
    console.log(item);
}

它记录下了: 'one', 'two' 和 'three'

而倒序打印,则可以使用更加高效的循环:

var items = ['one', 'two', 'three'], i = items.length;
while(i--){
    console.log(items[i]);
}

它记录:'three','two'和'one'

或者传统的for循环:

var items = ['one', 'two', 'three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

它记录了:'one','two','three'

参考:Google Closure: How not to write JavaScript


21
如果数组元素中有任何一个为假值,在 "while" 语法的第一个示例将无法工作。 - Chris Cooper
2
这个 while 循环等同于:for (var i=0,item; item=items[i]; i++),这样就不需要事先声明索引和项变量了。 - Stijn de Witt

40

使用函数式编程的方式在JavaScript中循环遍历数组的一些用例:

1. 只需循环遍历数组

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

注意:Array.prototype.forEach()严格来说不是函数式编程,因为它所接受的输入参数函数不应该返回一个值,因此不能被视为纯函数。

2. 检查数组中是否有任何元素通过测试

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. 转换为新数组

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

注意:map() 方法会对调用数组中的每个元素执行提供的函数,并使用函数返回值创建一个新数组。

4. 对特定属性求和并计算平均值

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. 基于原始数组创建一个新的数组,但不修改原数组

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. 统计每个分类的数量

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. 根据特定条件检索数组的子集

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

注意:filter() 方法通过提供的函数实现测试,创建一个新数组,其中包含所有通过测试的元素。

8. 对数组进行排序

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

在这里输入图像描述

9. 在数组中查找元素

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

enter image description here

Array.prototype.find()方法返回数组中第一个满足所提供测试函数的元素的值。

参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接