举例说明如何使用JavaScript的map() 方法,以及它是如何工作的

97 阅读7分钟

简介

遍历序列可以用来访问和显示序列中的元素--但更多时候,它是为了在每个或某些元素上运行一个操作。

**注:**对一个序列的每个元素应用一个函数,并将转换后的结果返回到一个新的序列中,这被称为映射,其中原始序列的每个元素,Ex ,映射到新序列的一个潜在的转换元素,Exi

像大多数语言一样,JavaScript有一个映射操作的有效实现,它被内置到Array 类中。

在本指南中,你将学习如何使用JavaScript的map() 方法,以及它是如何工作的,在实际的代码例子上。

JavaScript的*map()*方法

让我们通过for-loop 语法,看看我们如何对每个元素应用某些方法。假设我们有一组分数,并希望给每个人加5分,以协助提高分数。

const mathScores = [39, 50, 45, 41, 50]; 
let newScores = [];
  
for (let i = 0; i < mathScores.length; i++) {
    newScores.push(mathScores[i] + 5);
}

console.log(newScores); // [44,55,50,46,55]

在上面的代码中,我们在mathScores 数组中循环,给每个成员增加5分,然后将新的分数推到newScores 数组中。

这是一个非常标准的程序,与map() 的工作非常相似。

Array.map() 方法遍历一个数组,并对每个元素应用回调函数,在一个新的数组中返回结果元素。

语法

该方法的语法是相当简单的。

const newArray = oldArray.map((currentValue, index, array)=>{
    // Do stuff with currentValue
})

indexarray 是可选的,可以用来访问currentValue索引和原始数组本身。

  • newArray - 应用 函数后,返回的新数组。map()
  • oldArray - 函数对原始数组进行操作,并不改变它。map()
  • currentValue - 函数在步骤 中处理的值,其中函数定义了在步骤 中发生的事情。map() X X
  • index - 当前值的索引。
  • array - 一个可选的参数,指向原始数组。

为了获得直观的视觉体验--你可以尝试记录这些值,并只返回原来的值,不做任何改变。

const mathScores = [39, 50, 45, 41, 50];
  
mathScores.map((currentValue, index, array) => {
    console.log('Current value:' + currentValue);
    console.log('Index:' + index);
    console.log('Array:' + array);
    return currentValue;
})
"Current value:39"
"Index:0"
"Array:39,50,45,41,50"
...
"Current value:50"
"Index:4"
"Array:39,50,45,41,50"

*map()*是如何工作的?

map() 函数,为了所有的实际目的,需要元素来工作--但是如果你调用map() 的数组是空的,它将只是返回一个空数组。它可以与箭头函数或普通函数一起使用。

在ES6之前,你通常将回调定义为。

const codes = [101, 201, 301, 303, 202];
let mathCodes = codes.map(function(code) {
    return `mth${code}`;
});
  
console.log(mathCodes); //["mth101","mth201","mth301","mth303","mth202"]

然而,在ES6中,你可以使用箭头函数来使代码更简洁。

const codes = [101, 201, 301, 303, 202]; 
let mathCodes = codes.map((code)=>{
    return `mth${code}`;
});
  
console.log(mathCodes); //["mth101","mth201","mth301","mth303","mth202"]

map() 示例

让我们来看看map() 函数的几个例子!例如,我们来计算列表中每个数字的平方根。

const numbers = [9, 36, 64, 144];
  
let squareRoots = numbers.map((number) => {
    return Math.sqrt(number);
});
  
console.log(squareRoots); // [3,6,8,12]

或者,我们可以将每个元素映射为其长度。

const names = ["Bilbo", "Gandalf", "Nazgul"];
let lengths = names.map((name) => name.length);
console.log(lengths); // [5,7,6]

或者,我们可以将每个学生对象映射到他们的名字和姓氏。

const students = [
    {firstName : "John", lastName: "Doe"},
    {firstName : "Stephen", lastName: "Matt"},
    {firstName : "Abigail", lastName: "Susu"}
];
  
let studentsNames = students.map(student => {
      return `${student.firstName} ${student.lastName}`;
})
  
console.log(studentsNames); // ["John Doe","Stephen Matt","Abigail Susu"]

map() 函数在前端的一个真正常见的用例是将数据包裹在HTML中。

let cont = document.getElementById('#container');
  
let users = [
    { firstName : "John", lastName: "Doe", age: 17 },
    { firstName : "Stephen", lastName: "Matt", age: 16 },
    { firstName : "Abigail", lastName: "Susu", age: 15 }
];
  
let singleUser = users.map((user)=>{
    // Let's add the firstname and lastname together
    let fullName = user.firstName + ' ' + user.lastName;
    return `
      <h3 class='name'>${fullName}</h3>
      <p class="age">${user.age}</p>
    `
});
  
container.innerHTML = singleUser;

*map()*与其他迭代器方法的比较?

map() 是JavaScript中迭代器方法的一个例子,了解什么时候你想利用哪种迭代器方法是非常有用的。迭代器方法使你能够在一个数组中的所有对象上进行循环,以执行特定的操作。

当决定是否利用map() 函数时,最好考虑一下其他的迭代器技术是否更合适。

下面是JavaScript中的一些额外的迭代器方法。

  • reduce()。减少操作是函数式编程中最强大的操作之一,通常涉及一个向量减少到一个标量(一个值的列表,到一个单一的值)。这可以是对一个数组中的所有值进行求和,找到平均数、最小值或最大值,或者以任何其他方式将一个较长的数据集减少到一个较小的数据集,源于原始数据。
  • filter()。过滤允许你从一个列表中过滤出不符合某些特定标准的项目,并返回一个符合标准的剩余项目的数组。
  • forEach()。类似于for...loopforEach() ,对列表中的每个项目执行一个函数。它允许你在一个数组中进行循环,并对每一个项目执行工作。

在某种程度上,这引出了一个问题。

map()forEach() 之间有什么区别?

map() vs forEach()

因为这两个方法都是通过一个数组运行,并用于对每个成员应用一个函数,所以map()forEach() 方法可能看起来极其相似。

这两个方法的主要区别是:map() 函数返回一个新的数组,而forEach() 方法则没有,它改变了原来的数组

此外,在map() 函数的每一次迭代中,你将return 一个被转换的元素。使用forEach() ,你不返回它们,但可以在上面运行函数,就地改变元素。虽然,你甚至不需要在元素上运行一个函数!

这使得forEach() ,当它涉及到,比如说,记录值,而不改变它们时,更可取。

const characters = ['z', 'y', 'x', 'w'];
  
characters.forEach(character => {
    console.log(character);
});

而如果你的目的是改变元素,map() 是首选。

在其他数组方法中使用map()

map() 方法来自于函数式编程--对于函数式编程,链式方法就像呼吸一样自然。函数式操作的连锁是非常普遍的,并且可以提供非常复杂的操作管道。

让我们来看看如何将map()Array 类的其他一些函数式方法连锁起来。

使用map()filter()

过滤通常是流水线中的第一个操作,因为对可能不包括在结果中的元素运行操作是没有效率的,除非你过滤的标准取决于流水线中的其他操作。

一个常见的步骤顺序是根据某个标准filter() 一个数组,然后再map() 剩余的元素。

让我们创建一个学生数组来过滤和映射。

const mathStudents = [
    {
      name: 'Jane',
      score: 60,
      enrollmentYear: 2019
    },
    {
      name: 'Emmy',
      score: 40,
      enrollmentYear: 2020
    },
    {
      name: 'John',
      score: 43,
      enrollmentYear: 2019
    },
    {
      name: 'Linda',
      score: 20,
      enrollmentYear: 2019
    }
]

现在,让我们根据学生的年份来过滤--只得到上一代的学生,然后映射他们的分数。

我们将把分数映射为 "及格"/"不及格 "的等级,以获得更符合人类需要的格式。

const passingStudents = mathStudents
    .filter((student) => student.enrollmentYear < 2020)
    .map((student) => {
      if (student.score > 40) {
        return student.name + ': passing'
      } else return student.name + ': not passing'
    });

console.log(passingStudents); // ["Jane: passing","John: passing","Linda: not passing"]

使用map()reverse()

有时你可能需要在执行其他操作之前或之后反转一个数组。这可以通过使用reverse() 函数很容易地完成。

const numbers = [21, 32, 43, 54, 65];
const newNumbers = numbers.map((number) => number * 2).reverse();
  
console.log(numbers); // [21,32,43,54,65]
console.log(newNumbers); // [130,108,86,64,42]

我们在循环的最后插入了reverse() 函数,这样它就可以反转得到的数组。如果我们把reverse() 调用放在map() 调用之前--我们实际上会反转原始数组,并映射其元素,而不是反转新的结果数组。

const numbers = [21, 32, 43, 54, 65];
const newNumbers = numbers.reverse().map((number) => number * 2);
  
console.log(numbers); // [65,54,43,32,21]
console.log(newNumbers); // [130,108,86,64,42]

在一个对象上使用map()

在使用对象静态方法(Object.keys(),Object.values(), 和Object.entries() )获得值、键或键值对之后,也可以在对象上使用map() 函数。因为这些对象静态方法中的每一个都会产生一个数组,map() 可以简单地与每一个数组相连接。

const scores = { math: 50, English: 70, Physics: 45, Agric: 60 };  
let newScores = Object.values(scores).map((score) => score + 5);
  
console.log(newScores); // [55,75,50,65]

结论

在本指南中,我们看了一下JavaScript中的map() 方法。

该方法遍历一个数组,对数组中的每个元素应用一个函数,并将新的元素序列作为一个新数组返回。我们通过实际例子看了该方法的语法、参数和用法。

此外,我们还比较了map() 方法和forEach() 方法,并探讨了如何将map()filter()reverse() 和对象相连接。