实现lodash的chunk方法--数组按指定长度拆分
手写实现lodash库中的chunk方法,将数组按照指定长度拆分成多个子数组
问题
实现一个 chunk 函数,将一个数组按照指定的长度拆分成多个子数组。如果数组无法被平均分割,最后一个子数组将包含剩余的元素。
例如:chunk([1, 2, 3, 4, 5], 2) 应该返回 [[1, 2], [3, 4], [5]]
解答
/**
* 将数组按指定长度拆分成多个子数组
* @param {Array} array - 需要处理的数组
* @param {number} size - 每个子数组的长度
* @returns {Array} 返回拆分后的二维数组
*/
function chunk(array, size = 1) {
// 参数校验
if (!Array.isArray(array)) {
return [];
}
// size 必须是大于 0 的整数
if (size < 1 || !Number.isInteger(size)) {
return [];
}
const result = [];
// 方法一:使用 for 循环和 slice
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}
return result;
}
// 方法二:使用 while 循环
function chunk2(array, size = 1) {
if (!Array.isArray(array) || size < 1 || !Number.isInteger(size)) {
return [];
}
const result = [];
let index = 0;
while (index < array.length) {
result.push(array.slice(index, index + size));
index += size;
}
return result;
}
// 方法三:使用 reduce
function chunk3(array, size = 1) {
if (!Array.isArray(array) || size < 1 || !Number.isInteger(size)) {
return [];
}
return array.reduce((result, item, index) => {
// 每 size 个元素创建一个新的子数组
if (index % size === 0) {
result.push([item]);
} else {
// 将元素添加到最后一个子数组
result[result.length - 1].push(item);
}
return result;
}, []);
}
使用示例
// 基本使用
console.log(chunk([1, 2, 3, 4, 5], 2));
// 输出: [[1, 2], [3, 4], [5]]
console.log(chunk([1, 2, 3, 4, 5, 6], 3));
// 输出: [[1, 2, 3], [4, 5, 6]]
console.log(chunk([1, 2, 3, 4, 5], 1));
// 输出: [[1], [2], [3], [4], [5]]
// 边界情况
console.log(chunk([], 2));
// 输出: []
console.log(chunk([1, 2, 3], 5));
// 输出: [[1, 2, 3]]
console.log(chunk([1, 2, 3, 4], 0));
// 输出: []
console.log(chunk([1, 2, 3, 4]));
// 输出: [[1], [2], [3], [4]] (默认 size 为 1)
// 处理字符串数组
console.log(chunk(['a', 'b', 'c', 'd', 'e'], 2));
// 输出: [['a', 'b'], ['c', 'd'], ['e']]
// 处理对象数组
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
{ id: 4, name: 'David' }
];
console.log(chunk(users, 2));
// 输出: [[{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }],
// [{ id: 3, name: 'Charlie' }, { id: 4, name: 'David' }]]
关键点
- 参数校验:需要验证输入是否为数组,size 是否为大于 0 的整数
- 默认参数:size 默认值设为 1,符合 lodash 的行为
- slice 方法:使用
array.slice(start, end)来截取子数组,不会修改原数组 - 循环步长:每次循环递增 size,确保不重复不遗漏
- 边界处理:当数组长度不能被 size 整除时,最后一个子数组自动包含剩余元素
- 性能考虑:方法一(for + slice)性能最优,代码简洁易懂,推荐使用
- 不可变性:所有方法都不会修改原数组,返回新的二维数组
目录