0%

非常彈性好用的陣列 Array 方法 map()

Day 32

如果日行一善可以持續,那鐵人應該也可以。

上一篇我們講解了陣列方法的 forEach(),知道它可以做迭代這件事,但在 ECMAScript 5 的陣列方法中大部分的方法都是以迭代為基礎,map()也是。

map()算是陣列方法中最實用的方法之一,我們可以用map()來轉換陣列內的元素,轉換成什麼可由我們決定,以我們想要的方式轉換後,map()會幫我們這些轉換結果,放入另一個新的陣列,回傳回來。

例如,我們有一個含有數字的物件,但只想要取出裡面的數字;或是,我們的陣列裡包含了函式 是啊,陣列裡也可放函式沒忘吧? 但我們需要這些函式的 promise,map()可以幫我們把元素轉換成另一個格式傳回來。

在「JavaScript 學習手冊」這本書裡有許多範例(有部分修改),我們來試著理解一下:

1
2
3
4
5
6
7
8
9
10
11
const shoppingCart = [
{ itemName: 'Book', price: 220 },
{ itemName: 'Bag', price: 350 }
];
const itemNames = shoppingCart.map(x => x.itemName);
// 只把 itemNames 提取出來
itemNames; // ["Book", "Bag"]

// 把 price 打七九折後提取出來
const discounts = shoppingCart.map(x => x.price * 0.79);
discounts; // [173.8, 276.5]

當然,用在陣列上也是ㄧ樣的方法:

1
2
3
4
const arr = [1, 2, 3, 4, 5, 6];
newArr = arr.map(x => x * x);

newArr; //  [1, 4, 9, 16, 25, 36]

Array.prototype.map() - JavaScript | MDN
原型: Array.prototype.map();
功能: 建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。
回傳值: 回傳新陣列,原陣列不改變。對陣列中的各元素進行操作,操作後的值會被寫入新的陣列中並返回。
參數: callback 函式和thisArg第二參數可忽略,可參考前一篇的forEach
改變: 不會改變原陣列。
語法: var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])

當我們提供的函式被呼叫的時候,這個函式會使用我們之前提到的 callback 函式的三個參數:元素本身、元素索引和陣列本身。陣列本身這個參數通常比較少用到,利用參數的特性,我們可以輕易地取到我們想要的值和索引:

1
2
3
4
5
const arr = [1, 2, 3, 4, 5, 6];
const arr2 = arr.map(function(element, index, array) {
return element * 2;
});
arr2.join('、'); // 2、4、6、8、10、12

map()也可以做到修正陣列這件事,架設我們有一個價格的陣列,只要不超過金額 50 的商品就標示「無折扣」,那麼我們就可以利用map()來過濾與修改這些值。

1
2
3
4
5
6
7
const prices = [42, 57, 89, 23, 78, 12];
const newPrices = prices.map(function(elem) {
if (elem < 50) return 'no Discount';
return elem;
});

newPrices; //  ["no Discount", 57, 89, "no Discount", 78, "no Discount"]

map()也有一些超級好用的用法。例如,假設我們有兩個不同的陣列,分別是產品名稱和價格,但我們想把它們結合在一起,就可以輕易的利用map()提取元素和索引的特性,來組合成另一組資料。:

1
2
3
4
5
6
7
8
9
10
11
const items = ['book', 'cap', 'bag'];
const prices = [125, 76, 390];
const listItems = items.map((elem, index) => ({
itemName: elem,
price: prices[index]
}));

listItems;
// [{itemName: "book", price: 125},
// {itemName: "bag", price: 390},
// {itemName: "bag", price: 390}]

是不是很神奇?我們在listItems使用了索引的提取,為什麼需要索引?是因為我們想要把itemsprices裡的元素用它們的索引連結起來。

map()本身是回傳陣列,我們希望的是物件的資料格式,所以從兩個陣列中提取我們所要的資訊,在 callback 函式裡前後加上{},再把我們提取的元素放入,回傳就會是物件了。

需要注意的是,我們必須用( )將物件格式包起來,如果沒包起來,箭頭函式的寫法會將大括號視為區塊標示。

今天的陣列 Array 方法 map()就介紹到此,接下來的陣列方法會繼續持續下去喔~

如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~