Як розбити масив у JS?

6 хв. читання

У цій статті ви навчитесь використовувати різні підходи, щоб розбивати масиви у JavaScript на частини визначеної розмірності.

1. Цикл for і функція slice

Взагалі то, у кожному способі буде використовуватися slice. Проте цей приклад робить особливим саме цикл for. У випадку неоднорідного масиву, необхідні елементи будуть знаходитись у масиві, проте з очевидних причин розмірність буде зменшено.

/**
 * Повертає масив, кожен з елементів якого містить інший масив заданої розмірності
 *
 * @param myArray {Array} Масив для розбиття
 * @param chunk_size {Integer} Розмір вихідних груп
 */
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);
        // Можна провести будь-які операції над вихідними групами
        tempArray.push(myChunk);
    }

    return tempArray;
}
// Розбиття на групи по 3 елементи
var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Повертає : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

2. Цикл for, slice і функції set у прототипі масиву

Ви можете оголосити власні методи у прототипі функції, наприклад, можна створити функцію з іменем chunk:

/**
 * Оголосити метод chunk у прототипі масиву
 * Він буде повертати масив, кожен елемент якого буде мати визначену розмірність.
 *
 * @param chunkSize {Integer} Розмір кожної групи
 */
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;
    }
});
// Розбиття на групи по 3 елементи
var result = [1,2,3,4,5,6,7,8].chunk(3);
// Повертає : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

Як ви можете побачити, принцип роботи полягає у використанні for і slice, проте на відміну від використання функції, ми реєструємо метод у прототипі об'єкта array.

3. Використання array map у прототипі масиву

Функція map викликає колбек для кожного елементу масиву по черзі й будує новий масив з результатів роботи колбек-функції. Функція повертає масив з довжиною визначеною діленням довжини масиву на розміри секцій. Функція заповнення наповнить створений масив невизначеними даними й, нарешті, кожне невизначене значення у масиві буде замінене новим масивом з відповідним індексом.

/**
 * Оголосити метод chunk у прототипі масиву
 * Він буде повертати масив, кожен елемент якого буде мати визначену розмірність.
 *
 * @param chunkSize {Integer} Розмір кожної групи
 */
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);
        });
    }
});

// Розбиття на групи по 3 елементи
var result = [1,2,3,4,5,6,7,8].chunk(3);
// Повертає : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

4. Використання циклу while та методу splice

За нормальних умов цикл while працює дещо швидше, ніж інші приведені тут варіанти. У будь-якому випадку нам слід пам'ятати, що приріст продуктивності помітно лише за умови великої кількості ітерацій. Тому, якщо ваш масив має значну розмірність, і ви хотіли б розділити його на частини з невеликою кількістю елементів, вам слід використовувати метод, який базується на while, щоб підвищити продуктивність.

**
  * Повертає масив, кожен з елементів якого містить інший масив заданої розмірності
 *
 * @param myArray {Array} Масив для розбиття
 * @param chunk_size {Integer} Розмір вихідних груп
 */
function chunkArray(myArray, chunk_size){
    var results = [];
    
    while (myArray.length) {
        results.push(myArray.splice(0, chunk_size));
    }
    
    return results;
}

// Розбиття на групи по 3 елементи
var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Повертає : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

5. Рекурсивне використання slice і concat

Якщо говорити про швидкість роботи й використання ресурсів браузера, то рекурсія може значно зашкодити продуктивній роботі вашого застосунку. Крім того, функція concat у деяких браузерах може відпрацьовувати помітно повільніше за метод join.

/**
 * Оголошення методу chunk у прототипі масиву
 * Він буде повертати масив, кожен елемент якого буде мати визначену розмірність (Рекурсивно).
 *
 * @param chunk_size {Integer} Розмір вихідних груп
 */
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 елементів на три рівні частини 1000 разів підряд. Так ми досягнемо найбільшої можливої точності результатів тестування.

Тестування проводилось на наступній системі:

  • Operative system Windows 10 Pro 64-bit
  • Chrome 53.0.2785.116 m (64-bit)
  • Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz (4 CPUs), ~3.3GHz
  • 8192MB RAM
Метод Загальний час Середній час ітерації
Цикл for 5778.015000000001 5.776805000000013
Цикл for у прототипі масиву 5681.145 5.679875000000007
Array map у прототипі масиву 8855.470000000001 8.854190000000001
Цикл while 1468.6650000000002 1.468275000000002
Рекурсивна function що, містить slice і concat Краш тесту Краш тесту
  • Цикл while виявився найшвидшим способом розбиття масиву на частини, і показав високу продуктивність у порівнянні з іншими.
  • Варто зазначити, що чим більша кількість елементів буде знаходитись в окремому фрагменті масиву, тим швидше виконається завдання
  • Під час виконання методу №5 браузер видає помилку, тому його використання для великої кількості даних не рекомендується.
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.9K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація