У цій статті ви навчитесь використовувати різні підходи, щоб розбивати масиви у 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 браузер видає помилку, тому його використання для великої кількості даних не рекомендується.
Ще немає коментарів