iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
JavaScript

入門JavaScript系列 第 17

迴圈應用

  • 分享至 

  • xImage
  •  

JavaScript 迴圈的進階應用可以解決複雜的資料處理、優化性能、處理異步操作和操作結構化數據等問題。

1. 處理多維陣列

多維陣列是巢狀結構,需要巢狀迴圈來處理。為了處理如矩陣、表格數據這樣的資料結構,巢狀迴圈和遞迴經常被使用。

範例:矩陣轉置(Transpose)

將矩陣的行和列進行轉換。

function transpose(matrix) {
  const result = [];
  for (let i = 0; i < matrix[0].length; i++) {
    const row = [];
    for (let j = 0; j < matrix.length; j++) {
      row.push(matrix[j][i]);
    }
    result.push(row);
  }
  return result;
}

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

console.log(transpose(matrix));
// [
//   [1, 4, 7],
//   [2, 5, 8],
//   [3, 6, 9]
// ]

2. 異步迴圈應用

當你需要在迴圈中進行異步操作(如網路請求、資料庫查詢),使用 async/await 是最佳選擇。這樣可以確保每次異步操作完成後再繼續下一個步驟。

範例:串行執行 API 請求

async function fetchData(url) {
  const response = await fetch(url);
  const data = await response.json();
  return data;
}

async function fetchMultipleData(urls) {
  for (let url of urls) {
    const data = await fetchData(url);
    console.log(data);
  }
}

const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
fetchMultipleData(urls);

3. 使用 reduce() 進行陣列的高效處理

reduce() 可以用來執行複雜的資料聚合邏輯,這對於需要處理大量數據的情況尤其有用。reduce() 可以取代多層次的巢狀迴圈,並使程式碼更簡潔。

範例:計算物件陣列中的總和

const transactions = [
  { amount: 50 },
  { amount: 75 },
  { amount: 100 },
  { amount: 200 }
];

const total = transactions.reduce((sum, transaction) => sum + transaction.amount, 0);
console.log(total); // 425

4. 跳脫巢狀迴圈中的 break

在巢狀迴圈中,如果要中斷內外層的迴圈,傳統的 break 無法中斷外層迴圈。可以使用標籤(label)與 break 來達成這個需求。

範例:跳脫巢狀迴圈

outerLoop: // 定義標籤
for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    if (i === 2 && j === 3) break outerLoop;
    console.log(i, j);
  }
}

// 輸出
// 0 0, 0 1, 0 2, 0 3, 0 4
// 1 0, 1 1, 1 2, 1 3, 1 4
// 2 0, 2 1, 2 2

5. 生成器(Generator)與可迭代物件

使用生成器(Generator function),可以創建可中斷的迴圈,這在需要延遲計算或逐步生成數據時非常實用。

範例:斐波那契數列生成器

function* fibonacci() {
  let a = 0, b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5

6. 批次處理(Batch Processing)

處理大量資料時,為了優化性能,可以分批處理,避免一次操作太多資料導致性能下降。這種技術常用於處理大陣列、API 請求、或 DOM 操作。

範例:分批處理大數據

function processBatch(items, batchSize) {
  let index = 0;
  function processNextBatch() {
    const batch = items.slice(index, index + batchSize);
    for (let item of batch) {
      console.log(item);
    }
    index += batchSize;
    if (index < items.length) {
      setTimeout(processNextBatch, 100); // 延遲處理下一批
    }
  }
  processNextBatch();
}

const largeArray = Array.from({ length: 1000 }, (_, i) => i + 1);
processBatch(largeArray, 100);

7. 迴圈內存優化:提前返回與避免不必要的計算

當處理大量數據或有昂貴的計算過程時,提前結束迴圈(如使用 breakreturn)或跳過無效計算(使用 continue)可以提升性能。

範例:找出符合條件的第一個值並提前返回

function findFirstEven(numbers) {
  for (let num of numbers) {
    if (num % 2 === 0) return num; // 找到第一個偶數立即返回
  }
  return null;
}

console.log(findFirstEven([1, 3, 5, 7, 8, 9])); // 8

8. for await...of 處理異步可迭代物件

這是一種用來處理異步可迭代數據的迴圈,適合用在需要逐一處理異步資料來源的情境(例如多個 API 請求)。

範例:異步迭代多個 API 響應

async function* asyncGenerator() {
  const urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
  for (const url of urls) {
    const response = await fetch(url);
    yield response.json();
  }
}

(async function() {
  for await (const data of asyncGenerator()) {
    console.log(data);
  }
})();

總結

這些應用展示了 JavaScript 迴圈處理各種複雜情況的強大能力,無論是面對大量數據、提升程式的效率,還是處理異步操作。根據實際需求選擇合適的技巧,能讓程式碼更簡潔易懂,執行起來也更快更順。


上一篇
迴圈
下一篇
函式
系列文
入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言