鲁斯前端布鲁斯前端

文章中英模式

布鲁斯前端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));