lodash源码之chunk

1、使用场景

_.chunk(array, [size=1])
将数组(array)拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果 array 无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。

_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
 
_.chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]

2、自己实现一个简单的chunk方法

看到 chunk 方法的使用示例之后,自己实现了一个简单 chunk 函数,不过没有对参数的类型做太多的处理。

function chunk(arr, size = 1) {
  if(size >= arr.length) {
    return arr;
  } else if(size < 1) {
    return [];
  };
  const newArr = [];
  const loop = Math.ceil(arr.length / size);
  for(let i = 0; i < loop; i++) {
    newArr.push(arr.slice(i * size, (i + 1) * size));
  };
  return newArr;
};

3、源码分析

chunk.js

import slice from './slice.js'
import toInteger from './toInteger.js'

function chunk(array, size = 1) {
  size = Math.max(toInteger(size), 0)
  const length = array == null ? 0 : array.length
  if (!length || size < 1) {
    return []
  }
  let index = 0
  let resIndex = 0
  const result = new Array(Math.ceil(length / size))
  while (index < length) {
    result[resIndex++] = slice(array, index, (index += size))
  }
  return result
}

export default chunk

分析 chunk 这个函数,从函数传入的参数开始:
1. 参数

function chunk(array, size = 1)

如果 chunk() 这个方法只传一个参数,那么 size 默认取 1,传入的数组 array 就会被分割成长度是 1 的数组。即:chunk([1,2,3]) => [[1],[2],[3]]
2、对参数size的处理

size = Math.max(toInteger(size), 0)

首先解释 toInteger(size) 这个方法,这个方法可以把 size 转换成整数,如果 size 不能转换成 Number 类型,该方法就返回 0。Math.max 方法是取最大值。总结下来就是:

  • size 是负数和0、以及转换成 Number 类型后不是正数的,size = 0;
  • 别的情况 size = Math.floor(Number(size));

3、如果传入的array和size不符合,就直接返回[]

const length = array == null ? 0 : array.length
if (!length || size < 1) {
  return []
}

这里总结了返回 [] 的几种情况:

  • size < 1;
  • array 是空数组;
  • array 类型是:Boolean、undefined、null、Number;
如果参数类型都符合条件,就到了正式处理的环节了:
  let index = 0
  let resIndex = 0
  const result = new Array(Math.ceil(length / size))
  while (index < length) {
    result[resIndex++] = slice(array, index, (index += size))
  }
  return result
const result = new Array(Math.ceil(length / size))

这里先使用new Array让result成为一个固定长度的空数组,可能会比直接让它成为一个空数组性能更高一些;

 while (index < length) {
    result[resIndex++] = slice(array, index, (index += size))
  }

slice(array, index, (index += size)) 实际上就类似数组的 slice 方法,即:array.slice(index, index += size) 。
最后 把 result 这个数组 return 出去即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容