iT邦幫忙

2021 iThome 鐵人賽

DAY 12
2
Modern Web

JavaScript 魔法入門 - 從入門到中階觀念系列 第 12

入門魔法 - 常用陣列方法(一) 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


上一篇
入門魔法 - 了解 JSON 格式及內建方法
下一篇
入門魔法 - 常用陣列方法(二)find、findIndex
系列文
JavaScript 魔法入門 - 從入門到中階觀念30

尚未有邦友留言

立即登入留言