个性化阅读
专注于IT技术分析

如何在JavaScript中轻松将数组拆分为相同大小的块

在本文中, 你将学习使用不同的实现将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时, 浏览器崩溃, 因此不建议使用此方法获取大量数据。

玩得开心 !

赞(0)
未经允许不得转载:srcmini » 如何在JavaScript中轻松将数组拆分为相同大小的块

评论 抢沙发

评论前必须登录!