在本文中, 你将学习使用不同的实现将Javascript数组拆分为具有指定大小的块。
1.使用for循环和slice函数
基本上, 每个方法都将使用slice方法来拆分数组, 在这种情况下, 使该方法与众不同的是for循环。
如果数组不统一, 则其余项目也将位于数组中, 但是由于明显的原因, 其大小将减小。
/**
* Returns an array with arrays of the given size.
*
* @param myArray {Array} array to split
* @param chunk_size {Integer} Size of every group
*/
function chunkArray(myArray, chunk_size){
var index = 0;
var arrayLength = myArray.length;
var tempArray = [];
for (index = 0; index < arrayLength; index += chunk_size) {
myChunk = myArray.slice(index, index+chunk_size);
// Do something if you want with the group
tempArray.push(myChunk);
}
return tempArray;
}
// Split in group of 3 items
var result = chunkArray([1, 2, 3, 4, 5, 6, 7, 8], 3);
// Outputs : [ [1, 2, 3] , [4, 5, 6] , [7, 8] ]
console.log(result);
2.在数组原型中使用for循环, 切片和设置功能
你可以在函数原型中注册自定义函数, 在这种情况下, 你可以创建一个名称块来实现我们的目标的自定义函数:
/**
* Define the chunk method in the prototype of an array
* that returns an array with arrays of the given size.
*
* @param chunkSize {Integer} Size of every group
*/
Object.defineProperty(Array.prototype, 'chunk', {
value: function(chunkSize){
var temporal = [];
for (var i = 0; i < this.length; i+= chunkSize){
temporal.push(this.slice(i, i+chunkSize));
}
return temporal;
}
});
// Split in group of 3 items
var result = [1, 2, 3, 4, 5, 6, 7, 8].chunk(3);
// Outputs : [ [1, 2, 3] , [4, 5, 6] , [7, 8] ]
console.log(result);
如你所见, 使用for循环和slice函数的原理是相同的, 但不是在函数中使用它, 而是在数组的原型中注册。
3.在数组原型中使用数组映射
map函数依次对数组中的每个元素调用提供的回调函数, 然后从结果中构造一个新的数组。该函数将返回一个数组, 数组的长度由Providen数组的长度除以块的大小来定义。 fill函数(因为没有参数Providen)将使用未定义的值填充创建的数组, 最后, 该数组中的每个未定义值都将被一个新的数组替换(将Providen数组切成适当索引的结果)。
/**
* Define the chunk method in the prototype of an array
* that returns an array with arrays of the given size.
*
* @param chunkSize {Integer} Size of every group
*/
Object.defineProperty(Array.prototype, 'chunk', {
value: function(chunkSize) {
var that = this;
return Array(Math.ceil(that.length/chunkSize)).fill().map(function(_, i){
return that.slice(i*chunkSize, i*chunkSize+chunkSize);
});
}
});
// Split in group of 3 items
var result = [1, 2, 3, 4, 5, 6, 7, 8].chunk(3);
// Outputs : [ [1, 2, 3] , [4, 5, 6] , [7, 8] ]
console.log(result);
4.使用while循环和切片
在典型和正常情况下, while循环会稍快一些。但是, 我们应该意识到, 这些性能提升对于大量迭代而言非常重要。因此, 如果你的数组很大, 并且你希望将其拆分为低数量的块, 则应考虑使用使用while方法来大幅提高性能。
/**
* Returns an array with arrays of the given size.
*
* @param myArray {Array} Array to split
* @param chunkSize {Integer} Size of every group
*/
function chunkArray(myArray, chunk_size){
var results = [];
while (myArray.length) {
results.push(myArray.splice(0, chunk_size));
}
return results;
}
// Split in group of 3 items
var result = chunkArray([1, 2, 3, 4, 5, 6, 7, 8], 3);
// Outputs : [ [1, 2, 3] , [4, 5, 6] , [7, 8] ]
console.log(result);
5.在递归函数中使用slice和concat
在这种方法中, 如果我们谈论性能和浏览器资源, 则递归是相当昂贵的。此外, 在某些浏览器中, concat功能要比join方法慢得多。
/**
* Define the chunk method in the prototype of an array
* that returns an array with arrays of the given size (with a recursive function).
*
* @param chunk_size {Integer} Size of every group
*/
Array.prototype.chunk = function (chunk_size) {
if ( !this.length ) {
return [];
}
return [ this.slice( 0, chunk_size ) ].concat(this.slice(chunk_size).chunk(chunk_size));
};
免责声明:请勿在具有大量数据的生产环境中使用。
关于性能
我们的简单基准将是将100000(100K)个项目(仅数字)的数组拆分为每个数组3个项目的块。为了提供高精度, 将执行1000(1K)次此任务, 其值以毫秒为单位。
基准测试已在具有以下规格的计算机上执行:
- 操作系统Windows 10 Pro 64位
- Chrome 53.0.2785.116 m(64位)
- Intel(R)CoreTM i5-4590 CPU @ 3.30GHz(4 CPU), 〜3.3GHz
- 8192MB内存
方法 | Total time (ms) | Average time per task (ms) |
---|---|---|
1(用于循环) | 5778.015000000001 | 5.776805000000013 |
2(用于原型中的循环) | 5681.145 | 5.679875000000007 |
3(原型中的数组图) | 8855.470000000001 | 8.854190000000001 |
4(while循环) | 1468.6650000000002 | 1.468275000000002 |
5(带有slice和concat的递归函数) | 测试崩溃 | 测试崩溃 |
- 与其他循环相比, while循环似乎是将数组拆分为多个块的最快方法。
- 基准测试中需要注意的一个细节是, 每个块中的项目数量越多, 任务执行得越快。
- 使用方法号5时, 浏览器崩溃, 因此不建议使用此方法获取大量数据。
玩得开心 !
评论前必须登录!
注册