陣列

陣列轉換 在 JavaScript

20 個練習

關於 陣列轉換

在 JavaScript 中,Array類別有許多強大的內建方法可以轉換陣列。相較於使用簡單的 for 迴圈或更直接的操作,這些方法讓陣列之間的轉換輕鬆許多。

有些方法是純的,意思是它們不會修改原始陣列,而是回傳一個新陣列。不過,其他方法則會操作呼叫它們的陣列,而且不會回傳修改後的陣列。

以下介紹幾個最常用來轉換陣列的方法。想查看所有可用方法的完整清單,請參閱 MDN 文件。

map(純)

根據透過引數傳入的函式來轉換每個元素,建立一個新的陣列。這些回呼函式通常會寫成箭頭函式。

let arr = [1, 2, 3, 4];

const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]

值得注意的是,產生出來的陣列長度一律與原始陣列相同。

filter(純)

給定一個過濾函式(元素應該保留時回傳 true,應該移除時回傳 false),從目前的陣列篩選出新的陣列。

let arr = [1, 2, 3, 4];

arr.filter((value) => value % 2 === 0);
// => [2, 4]

reduce(純)

使用一個接受_累加器_和陣列目前元素作為參數的函式,將陣列縮減成單一的值。這個函式說明了目前元素必須如何合併進累加器,並回傳下一次疊代要使用的累加器。

let arr = [1, 2, 3, 4];

// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10

// Classify the numbers by whether they are odd or not
arr.reduce(
  (accumulator, currentValue) => {
    if (currentValue % 2 === 0) {
      accumulator.even.push(currentValue);
    } else {
      accumulator.odd.push(currentValue);
    }

    return accumulator;
  },
  { even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }

reverse

反轉陣列中的元素。

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

arr.reverse();
// => [4, 3, 2, 1]

這個方法會修改呼叫它的陣列。

slice(純)

給定起始與結束索引,從呼叫它的陣列建立一個子陣列。

結束索引所在的元素不會包含在內。此外,所有參數都是選用的:起始索引預設為0,結束索引預設為陣列長度。

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

arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]

splice

可以移除、取代或新增陣列中的元素。它接受下列參數:

  • 開始修改陣列的元素索引
  • 要刪除的元素數量
  • 要插入陣列的元素(選用)

splice會回傳被移除的元素。

const arr = ['1', '2', '5', '6'];

// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']

// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']

// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']

sort

預設情況下,sort會先將陣列中的元素轉換成字串,再套用字串比較(請參閱概念比較)來排序。排序是_就地_進行的,也就是說原始陣列會被修改。sort也會回傳那個修改後的陣列,方便你將其他方法串接在後。

const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']
Caution

當你嘗試排序數字時,這個預設行為會導致錯誤的結果。

const arr = [3, 1, 2, 10];
arr.sort();
// => [1, 10, 2, 3]
// Because the string '10' comes before '2' in dictionary order.

若要自訂排序行為,你可以傳入一個比較函式作為引數。這個比較函式本身會以兩個引數來呼叫,也就是陣列中的兩個元素。它必須回傳下列其中一種結果:

  • 如果第一個引數應該排在第二個之前,回傳一個負數
  • 如果第一個引數應該排在第二個之後,回傳一個正數
  • 如果元素的順序應該維持不變,回傳0

如此一來,只要傳入正確的比較函式,就能解決數字排序的問題。

const arr = [3, 1, 2, 10];
arr.sort((a, b) => a - b);
// => [1, 2, 3, 10]
// "a - b" is negative when b is greater than a, positive when
// a is greater than b and 0 when they are equal.

以下範例說明如何使用自訂的比較函式來排序物件陣列。

const arr = [
  { name: 'Lydia', age: 7 },
  { name: 'Anne', age: 34 },
  { name: 'Holger', age: 59 },
];

arr.sort((item1, item2) => {
  if (item1.name < item2.name) {
    return -1;
  }
  if (item1.name > item2.name) {
    return 1;
  }
  return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]

自 2019 年起,語言規格便規定排序必須是穩定的,但對於效能(時間與空間複雜度)則沒有任何保證。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 陣列轉換