魯斯前端布魯斯前端

文章中英模式

布魯斯前端JS面試題目 - 實作陣列分塊函數

學習如何實作陣列分塊(chunk)函數,將大型陣列分割成等大小的子陣列,掌握數據處理與分頁顯示的實用技巧。

影片縮圖

懶得看文章?那就來看影片吧

陣列分塊(Chunk)函數概述

陣列分塊(Chunk)是一種常見的陣列處理技術,將一個大陣列分割成多個小陣列(子陣列),每個子陣列包含指定數量的元素。這在處理大量數據、批次操作和分頁顯示時非常有用。

常見應用場景

  • 1. 分頁顯示:將大量數據分成多頁展示
  • 2. 批量處理:將大量任務分成小批次執行,避免阻塞
  • 3. API 請求優化:將大量資料分批發送,避免請求過大
  • 4. UI 渲染優化:分批渲染大列表,提高性能
  • 5. 數據分析:將大數據集分成可管理的子集進行處理

實作基本的 Chunk 函數

下面是一個基本的 chunk 函數實作,可以將陣列分割成指定大小的子陣列:

function chunk(array, size) {
  if (!Array.isArray(array)) {
    throw new TypeError('Expected an array as the first argument');
  }
  
  if (size <= 0 || !Number.isInteger(size)) {
    throw new TypeError('Size must be a positive integer');
  }
  
  // 創建結果陣列
  const result = [];
  
  // 遍歷原陣列
  for (let i = 0; i < array.length; i += size) {
    // 使用 slice 方法取出一個子陣列
    result.push(array.slice(i, i + size));
  }
  
  return result;
}

// 使用範例
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(chunk(numbers, 3));
// 輸出: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

上面的實作使用了 slice 方法從原陣列中提取子陣列。我們以指定的 size 為步長遍歷陣列,每次取出 size 個元素。

實際應用場景

下面是一些陣列分塊函數的實際應用示例:

1. 分頁處理大量數據

// 模擬從 API 獲取的大量數據
const allUsers = [/* 假設這裡有 1000 個用戶數據 */];

// 分頁顯示設置
const pageSize = 10;
const totalPages = Math.ceil(allUsers.length / pageSize);

// 獲取指定頁碼的數據
function getPage(pageNumber) {
  // 檢查頁碼是否有效
  if (pageNumber < 1 || pageNumber > totalPages) {
    throw new Error('Invalid page number');
  }
  
  // 計算起始索引 (0-based)
  const startIndex = (pageNumber - 1) * pageSize;
  
  // 返回該頁數據
  return allUsers.slice(startIndex, startIndex + pageSize);
}

// 使用示例
const page1 = getPage(1); // 獲取第一頁數據
const page2 = getPage(2); // 獲取第二頁數據

// 前端分頁控制
document.getElementById('prev-button').addEventListener('click', () => {
  if (currentPage > 1) {
    currentPage--;
    renderUsers(getPage(currentPage));
    updatePagination();
  }
});

document.getElementById('next-button').addEventListener('click', () => {
  if (currentPage < totalPages) {
    currentPage++;
    renderUsers(getPage(currentPage));
    updatePagination();
  }
});

2. 批量處理 API 請求

// 假設我們需要處理大量 ID 的數據
const allIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, /* ... 更多 ID */];

// 批量處理函數
async function processBatch(ids) {
  // 模擬 API 請求
  console.log(`Processing batch of ${ids.length} ids: ${ids.join(', ')}`);
  
  // 假設這是一個 API 調用
  return fetch('/api/process', {
    method: 'POST',
    body: JSON.stringify({ ids }),
    headers: { 'Content-Type': 'application/json' }
  }).then(response => response.json());
}

// 分批處理所有 ID
async function processAllIdsInBatches(ids, batchSize = 3) {
  const batches = chunk(ids, batchSize);
  const results = [];
  
  for (const batch of batches) {
    try {
      // 依次處理每一批
      const result = await processBatch(batch);
      results.push(result);
      
      // 可以添加延遲,避免請求過快
      await new Promise(resolve => setTimeout(resolve, 1000));
    } catch (error) {
      console.error(`Error processing batch ${batch}:`, error);
    }
  }
  
  return results.flat();
}

// 使用示例
processAllIdsInBatches(allIds, 3)
  .then(results => console.log('All processing complete:', results))
  .catch(error => console.error('Processing failed:', error));