preface
The chunk function in Lodash is a useful array-utility function that creates a new array, slicing and grouping the incoming arrays according to the size parameter. If the array is not divisible at the end, the rest of the elements are put in the last block
Although the principle of this function is relatively simple, in order to deal with some boundary cases in LoDash, it is very careful to do a lot of conditional judgment and processing for this function, so it is very robust, corresponding to similar array objects can also be processed
Thought analysis
Source code analysis
chunk
1. Pass in parameters:
array
Passing in an arraysize
Pass in a number that determines the number of elements in the new arrayguard
Passed an iterator object that is intended to be used in conjunction with the iterative method
2. Source code analysis
function chunk(array, size, guard) {
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
size = 1;
} else {
size = nativeMax(toInteger(size), 0);
}
var length = array == null ? 0 : array.length;
if(! length || size <1) {
return [];
}
var index = 0,
resIndex = 0,
result = Array(nativeCeil(length / size));
while (index < length) {
result[resIndex++] = baseSlice(array, index, (index += size));
}
return result;
}
Copy the code
The default size is 1 if guard is set or size is not set; If size is passed to anything else, it is cast as an integer
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
size = 1;
} else {
size = nativeMax(toInteger(size), 0);
}
Copy the code
Check whether the array is empty, and then check whether the length attribute of the passed object exists, or whether size is negative, if not return the empty array
var length = array == null ? 0 : array.length;
if(! length || size <1) {
return [];
}
Copy the code
Class, copy the element in the specified position into the new array using the baseSlice method, and assign it to result. Returns result
var index = 0,
resIndex = 0,
result = Array(nativeCeil(length / size));
while (index < length) {
result[resIndex++] = baseSlice(array, index, (index += size));
}
return result;
Copy the code
baseSlice
1. Pass in parameters
array
Passing in an arraystart
Incoming copy starting pointend
Incoming replication endpoint
2. Source code analysis
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
Copy the code
Initialize, and convert both start and end to positive numbers. Note that if start and end were originally negative numbers, start and end numbers are terminated from the end of the array
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
Copy the code
Unsigned right shift to start, the sign bit of the end – start result becomes a positive number and is rounded. Since numbers store binary complement, it is equivalent to adding 2^32 to a negative result to ensure that it is non-negative (positive if meaningful, default 0 if meaningless). Then index starts at 0 and assigns the array element corresponding to the start position to the result element at index position
length = start > end ? 0 : ((end - start) >>> 0); start >>>= 0; Var result = Array(length); while (++index < length) { result[index] = array[index + start]; } return result; }Copy the code
Array like object
Since chunk can be used to group array-like objects, array-like objects are also briefly described here
First of all, we can explicitly define an array-like object that has a length attribute and its attributes are all non-negative integers.
The Chrome object display with the splice method is converted from {} to []
There is also a corresponding judgment method in LoDash, isArrayLike, which is to judge the length attribute, I will also analyze the opportunity in the future
Unlike arrays, the archetypal chain of array-like objects, or their inherited ancestor type, does not have Array, and therefore cannot use forEach, Map, reduce, etc., which requires a for loop or for loop to iterate over them… In the for… Of cannot be used unless Symbol. Iterator is defined, because the object itself needs to be iterable
You can append a custom symbol. iterator
To manipulate an array-like object, you can also convert it directly to an array, in addition to the methods described above. Array.from is the built-in function that handles this situation, passing in the argument returns a new Array of the original object attributes in order
More class array object in the result of the DOM selection, such as document. QuerySelectorAll returns a NodeList class array object
conclusion
As an array method, the chunk method is often used to group the slices of an array. You can upgrade the dimension of the array and divide the array into chunks
The robustness of the chunk method itself also ensures that it can be used in class arrays
Lodash reuses the baseSlice method in its underlying implementation, so the chunk method is O(n^2).