入门魔法 - 常用阵列方法(一) forEach、filter、 map

前情提要

艾草:「你过来帮我摆一下魔法阵!」

「哇喔,看起来好厉害唷!这里有三个空位是要摆什麽吗?」

艾草:「对唷!魔法阵列内都能摆入三个参数,来这个你接着!摆到上方。」

「红萝卜...?」

艾草:「来这两个也给你,摆到左右两侧!」

「玉米...?青豆...? 你干嘛给我摆三色豆啦!!!」

艾草:「配色差不多漂亮就可以了啦,要拿宝石很重耶。准备好了吗!发动~~ 常用阵列魔法~~」

https://ithelp.ithome.com.tw/upload/images/20210926/201390660pQdGeD20V.png

(团队简介说用三色豆摆阵就一定要用三色豆摆啦 ψ(`∇´)ψ)


常用阵列方法(一)

今天介绍阵列方法并不会透过 ES6 箭头函式方式撰写,等後续补充箭头函式用法後,会再提到阵列方法的箭头函式缩写方式。

在 JavaScript 中阵列是很常被使用到的,今天要来介绍阵列的方法!

forEach()

forEach() 会将阵列内的每个值都遍历,且无法使用 return 中断。

forEach() 内会包含一个参数为函式。

而该函式可以带入三个参数(参数名称可自定义):

  1. currentValue 阵列正在执行的值
  2. index 正在执行值的索引值(选择性)
  3. array 执行的阵列本身(选择性)

先来透过简单的程序码认识 forEach() 吧!

let num = [1, 2, 3];
num.forEach(function (item, index, array) {
  console.log(item, index, array);
});

印出结果:

https://ithelp.ithome.com.tw/upload/images/20210926/20139066NrpEq1pANa.png

forEach 实作

forEach() 可以说是最常使用的阵列方法了,forEach() 很适合拿来组字串,下方为范例程序码:

let data = [
  {
    name: "艾草",
    stir: true
  },
  {
    name: "龟人",
    stir: false
  },
  {
    name: "烙诗",
    stir: false
  },
  {
    name: "筑茵",
    stir: false
  }
];

//透过在全域宣告 str 累加内文
let str = "";
data.forEach(function(item, index, array) {
  //判断是否会搅拌
  if (item.stir) {
    str += `会搅拌卤肉饭的人有${item.name}|`;
  } else {
    str += `不会搅拌卤肉饭的人有${item.name}|`;
  }
});
console.log(str);

执行後的结果:

https://ithelp.ithome.com.tw/upload/images/20210926/20139066PMFswVPLoQ.png

像这样透过 forEach() 组字串的同时,还可以知道自己有多边缘唷 இдஇ


filter()

filter() 将旧阵列中的所有值带入指定函式筛选後,通过条件的值保留至回传的新阵列中。

filter() 内会包含一个参数为函式。

而该函式可以带入三个参数(参数名称可自定义):

  1. element 阵列正在执行的值
  2. index 正在执行值的索引值(选择性)
  3. array 执行的阵列本身(选择性)
let arr = [1,2,3,4,5,6,7,8,9,10];
//透过旧阵列 arr 去跑 filter
let newArray = arr.filter(function(item,index,array){
	return item > 5 ;
})
// arr = [1,2,3,4,5,6,7,8,9,10];
// newArray = [6, 7, 8, 9, 10];

arr第一个值为1,1 < 5所以会回传 false,不回传至新阵列中,而执行到 6 时 6 > 5 所以会回传 true,而 filter() 会将 true 的值保留至回传的新阵列。

filter 实作

我们一样透过会不会搅拌卤肉饭来实际操作 filter() ,如果今天只想知道有谁会搅拌卤肉饭,可以这样写:

let data = [
  {
    name: "艾草",
    stir: true
  },
  {
    name: "龟人",
    stir: false
  },
  {
    name: "烙诗",
    stir: false
  },
  {
    name: "筑茵",
    stir: false
  }
];
//宣告一个新变数 newData
//透过 data 跑 filter 并将筛选的值赋予给 newData
let newData = data.filter(function (item, index, array) {
  //如果符合会搅拌
  if (item.stir) {
    //回传该值
    return item;
  }
});
console.log(newData);

印出结果:

https://ithelp.ithome.com.tw/upload/images/20210926/20139066S4OBHLnF5o.png

透过这种方式,可以把那些卤肉饭胆敢不搅拌的队友们筛选掉,送辣 o(^▽^)o


map()

map()会处理旧阵列的每一个值,将阵列中的所有值带入指定函式转换或运算後回传至新阵列。

map() 内会包含一个参数为函式。

而该函式可以带入三个参数(参数名称可自定义):

  1. currentValue 阵列正在执行的值
  2. index 正在执行值的索引值(选择性)
  3. array 执行的阵列本身(选择性)
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let newArray = arr.map(function (item, index, array) {
  return item * 2;
});
// arr = [1,2,3,4,5,6,7,8,9,10];
//newArray = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];

forEach()的用法相似,map()会处理每个带入阵列的值,但forEach()并不会回传值,所以无法return

map()filter() 的差异在 map() 会回传每个值,不像 filter() 会筛选,所以如果将刚刚 filter() 的例子改成 map() ,结果如下:

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
//透过旧阵列 arr 去跑 map
let newArray = arr.map(function (item, index, array) {
  return item > 5;
});
// arr = [1,2,3,4,5,6,7,8,9,10];
// newArray = [false,false,false,false,false,true,true,true,true,true];

map() 会去比对是否符合,并将比对结果透过布林值,回传至新阵列。

map() 实作

实作情境:假设生命魔法团队内成员都提升了新等级,并增加了魔力总量 100 ,那可以透过 map() 帮大家一起提升!

let lv1 = [
  {
    name: "艾草",
    mana: 1300
  },
  {
    name: "龟人",
    mana: 800
  },
  {
    name: "烙诗",
    mana: 1000
  },
  {
    name: "筑茵",
    mana: 1000
  }
];
//宣告一个新变数 lv2
//透过 lv1 跑 map 并将执行结果赋予给 lv2
let lv2 = lv1.map(function (item, index, array) {
  //宣告一个物件
  let obj = {};
  //新增物件内的属性名称(key)为 name ,并赋予其值为 lv1 阵列执行时 name 属性的值(value)
  obj.name = item.name;
  //新增物件内的属性名称(key)为 mana ,并赋予其值为 lv1 阵列执行时 mana 属性的值(value)+100
  obj.mana = item.mana + 100;
  //回传该物件
  return obj;
});
console.log(lv2)

印出结果:

https://ithelp.ithome.com.tw/upload/images/20210926/20139066K0kLmchI6r.png

像这样就轻松帮大家升级罗,为什麽我的魔力总量最高呢?绝对不是我自肥~

总结

  • forEach 不会回传新阵列,无法使用 return
  • filtermap 会回传新阵列

小练习

请问以下选项叙述何者错误?
A forEach 可以拿来组字串,且无法回传新阵列
B filtermap 皆会回传新阵列
C mapforEach 都会回传每个值到新阵列
D filter 可以只筛选出想要的值, map 会回传每个值

解答:选项 C ,阵列方法 forEach 并不会回传值到新阵列。

参考文献

JavaScript 必修篇 - 前端修练全攻略(六角学院)
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://ithelp.ithome.com.tw/articles/10215281


<<:  3D 物件档案 — .obj

>>:  Day 14 并非是一成不变的!

D15/ 为什麽 remember 是 composable function? - @Composable 是什麽

今天大概会聊到的范围 @Composable compose compiler & run...

服务器运作简介

今天是第一天,我先简单的介绍一下网站服务器是如何运作的。还有如果在遭遇大量流量时,可能会有哪些状况。...

IT铁人DAY 6-UML基本认识

  在进入Pattern的介绍之前,我觉得要先让大家认识一下UML这个东西,尤其是Class Dia...

Laravel 实战经验分享 - Day30 回头看看,以及未来要干嘛

到了铁人赛最後一天,其实自己一开始就从没设想如果完成了铁人赛会有什麽样的心情,只想着就算没梗没题材,...

[C 语言笔记--Day01] Hello World

第一次参加铁人赛,我打算连续写30天有关 C 语言的笔记, 内容大概就是我今天看到、或回想起了什麽内...