Lodash source code analysis ------- chunk function

Basic idea

Have not seen the internal implementation of the chunk function, write your own implementation based on the functions given in the official documentation.

The chunk function accepts two parameters. The first parameter is of type array, and the second parameter is of type number. Its function is to split the array into multiple blocks of size and combine these blocks into one New array. If the array cannot be divided into all equal length blocks, then the last remaining elements will form a block. Examples are as follows:

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

Here I did not traverse the entire array, this is not necessary, use the slice function of Aarry type for optimization:

  1. First of all, we must determine the parameter type of the incoming function. If it is not an array or the second parameter is not a number, an exception is thrown.
  2. Record the length of each split temporary array, use the entire length of the array and the number to be split
  3. See if the remainder is 0. If it is not 0, add 1 after the division. This is because we have to add as many elements as possible before
  4. There is a pit here. Our final part value must be an integer, and then the division operator returns IEEE754 floating point number by default, for example: 5/3 returns 1.666666667, which needs to be converted to int using parseInt
  5. After this, we only need to intercept part of the values ​​each time, and only need to loop size times to get the answer

Implementation code

(function(window){
    function chunk(arr, splitnum){
        /** 首先判断类型,如果类型不对,直接抛出异常 */
        if(typeof splitnum != 'number' || (Object.prototype.toString.call(arr) != '[object Array]')){
            throw Error("当前参数类型错误");
        }
        let rest = arr.length % splitnum;
        let newArr = [], part = (rest == 0 ? parseInt(arr.length / splitnum) : parseInt(arr.length / splitnum + 1));
        for(let index = 0; index < splitnum; index ++){
            let start = (index * part), end = ((start + part) > arr.length ? arr.length : (start + part));
            let tmpArr = arr.slice(start, end);
            newArr.push(tmpArr);
        }
        return newArr;
        
    }
    window.chunk = chunk;
})(window);
Published 17 original articles · praised 0 · visits 465

Guess you like

Origin blog.csdn.net/chizhonghang/article/details/105444833