# 灵活的操作 JavaScript 数组

# 课程目标

我们将在本节中探索更多数组方法,重点掌握 .filter,.map,.reduce 三种方法的使用

# 数组过滤器 filter

当你需要根据某些条件过滤数组时,.filter 是一个很实用的方法。.filter 将根据您指定的条件返回另一个包含原始数组中某些项目的数组。如下例子:

let numbers = [-1, -2, 1, 2, 3];

let positiveNumbers = numbers.filter(function(number) {
  return number > 0;
});
console.log(positiveNumbers); // [1,2,3]

# 数组过滤器 Map

.map(callback)方法允许您将一个数组转换为另一个数组。下面例子:

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

const doubled = numbers.map(function(number) {
  return number * 2;
});
console.log(doubled); // [2, 4, 6, 8]

# 数组过滤器 Reduce

.reduce() 就像数组中的哆啦 a 梦,.reduce() 可用于将输入数组转换为您想要的任何输出,同时保留原始数组,下面是 .reduce()的基础语法

const newValue = arr.reduce(function(accumulator, currentValue, index, array) {
  // Do stuff with accumulator and currentValue (index, array, and initialValue are optional)
}, initialValue);
  • newValue : 返回的新数字、数组、字符串或对象
  • arr : 正在操作的数组
  • accumulator :上一次迭代的返回值
  • currentValue :数组中的当前项
  • index : 当前项目的索引
  • array-reduce():被调用的原始数组
  • initialValue :用作最终输出初始值的数字、数组、字符串或对象

这里举一个 .reduce() 实现数组累加的例子:

const numbers = [1, 2, 3];

const sum = numbers.reduce((previous, current) => {
  return previous + current;
}, 0);

console.log(numbers); // [1, 2, 3]
console.log(sum); // 6

# 数组查找

当您需要在数组中查找某一个元素时,.find 方法和 .includes 方法也许可以帮助您

.find(callback)在数组上调用该方法时,您将返回与您指定的条件匹配的第一项。如果未找到任何项目,您将返回 undefined,如下面的例子

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

numbers.filter(function(number) {
  return number > 2;
}); // [3]

numbers.filter(function(number) {
  return number > 4;
}); // undefined

如果您需要在数组中查找某一个元素是否存在,但是不需要返回它时,.includes 方法会比 .find 方法更加适合您

.includes(item)方法是最简单的数组方法之一,因为它需要一个 item 而不是回调函数,如果 item 存在返回 true,否则返回 false。下面是一个例子:

const members = ["Amy", "Lisa", "Jennie"];

members.includes("Amy"); // true
members.includes("Jack"); // false

# 数组对象转字符串

当您拥有一个数组并将该数组呈现到网页时,该数组将自动转换为字符串。JavaScript 将自动调用.toString()数组的方法,该方法返回以逗号分隔的数组元素的字符串。这是它的工作原理:

const process = ["Step1", "Step2", "Step3"];
groceries.toString(); // "Step1,Step2,Step3"

以上有一个缺点只能用逗号来连接每一个单词,如果您想自定义其他的内容,比如使用 -> 来连接,可以使用 join()方法

const process = ["Step1", "Step2", "Step3"];
process.join("->"); // "Step1->Step2->Step3"

# 其他方法

数组的方法非常丰富,您可以下面文档中学习您感兴趣的数组方法:

# 任务一

这里我们给出一个学生的期末成绩单

let scores = ["88", "90", "100", "45", "60", "98", "32", "99", "80"];

请你根据以下要求,实现函数:

  • getTotalScore() 返回学生的总分数
  • getAverageScore() 获得学生的平均分
  • getFailScores() 如果分数大于等于 60,就达到及格标准,返回没有及格的分数
  • getAddFiveScores() 给学生的每一科目都加五分,如果分数超过了 100,就取 100 分
  • getPrize() 学生奖学金和每一门分数相关,只要一门分数超过 90 分,就可以得到 100 元奖励,算出学生可以得到奖金总数
/**
 * @description 计算学生的总分数
 * @param {array} scores
 * @return {number} 学生的总分数
 */
function getTotalScore(scores) {
  // your code here
}

/**
 * @description 获得学生的平均分
 * @param {array} scores
 * @return {number} 学生的平均分
 */
function getTotalScore(scores) {
  // your code here
}

/**
 * @description 获得挂科的分数
 * @param {array} scores
 * @return {array} 返回没有及格的分数
 */
function getFailScores(scores) {
  // your code here
}

/**
 * @description 获得加五分之后的成绩单,如果加五分之后,分数超过了100,就取100分
 * @param {array} scores
 * @return {array} 新的成绩单
 */
function getAddFiveScores(scores) {
  // your code here
}

/**
 * @description 计算学生奖学金
 * @param {array} scores
 * @return { number} 奖学金
 */
function getPrize(scores) {
  // your code here
}

# 任务二

利用数组方法实现下面的功能函数


// 实现两个数组拼接,返回一个新数组
function arrJoin(arr1,arr2){
    // your implement
}
//测试用例
let arr1 = ['1','2','3'];
let arr2 = ['3','6','1']
console.log(arrJoin(arr1,arr2)); -> ['1','2','3','3','6','1']

// 利用reduce()实现两个数组归并
function arrMerge(arr1,arr2){
    // your implement
}

//测试用例
let arr1 = ['1','2','3'];
let arr2 = ['3','6','1']
console.log(arrMerge(arr1,arr2)); -> ['1','2','3','6']

// 封装数组去重函数,去除数组中重复的元素,
function norepeat = function(){
   // your implement
}

//测试用例
let arr = ['a','ab','a'];
console.log(arr.norepeat()); -> ['a','ab']

// 实现方法检测数组是否包含特定值
function inArray(value){
  //your implement
}

//测试用例
let arr = ['a','ab','a'];
console.log(inArray(arr,'b')); -> false
console.log(inArray(arr,'a'));->true

let arr = ['a','ab','a'];
console.log(inArray(arr,'b'));->false
console.log(inArray(arr,'a'));->true

// 实现多维数组变为一维数组
function matrixElements(arr){
    //your implement
}

//测试用例
let rows = [[2, 3, 5], [1, 2, 4], [8, 5, 5]]
console.log(matrixElements(rows)) //[2,3,5,1,2,4,8,5,5]

# 任务三

编码实现数组和对象的相互转换

对象转为数组:

var scoreObject = {
  Tony: {
    Math: 95,
    English: 79,
    Music: 68,
  },
  Simon: {
    Math: 100,
    English: 95,
    Music: 98,
  },
  Annie: {
    Math: 54,
    English: 65,
    Music: 88,
  },
};

//实现对象转换为数组
function objToArr(obj) {
  var arr = [];

  //do something

  return arr;
}

如上有一个用来存储学习成绩的对象,编写一个函数,将其转为如下的二维数组

var scoreArray = [
    ["Tony", 95, 79, 68],
    ……
];

数组转为对象:

var menuArr = [
    [1, "Area1", -1],
    [2, "Area2", -1],
    [3, "Area1-1", 1],
    [4, "Area1-2", 1],
    [5, "Area2-1", 2],
    [6, "Area2-2", 2],
    [7, "Area1-2-3", 4],
    [8, "Area2-2-1", 6],
];

//实现数组转换为对象
function arrToObj(arr){
    var obj = ();

    //do something

    return obj
}

如上有一个用来存储多级菜单数据的数组,编写一个函数,将其转为如下的对象

var menuObject = {
    "1": {
        name: "Area1",
        subMenu: {
            "3": {
                name: "Area1-1"
            },
            "4": {
                name: "Area1-2",
                subMenu: {
                    "7": {
                        name: "Area1-2-3"
                    }
                }
            }
        }
    }
    ……
}

# 进阶任务

如果你很快就完成上面的任务,可以去 LeetCode 上去多进行一些练习。

# 提交

把你今天觉得做得最好的代码放在 Github 后进行提交。

# 总结

依然把今天的学习用时,收获,问题进行记录。

# 相关参考