10

Разделить массив на части

8

Описание проблемы:

У меня есть массив JavaScript следующего вида:

["Element 1", "Element 2", "Element 3", ...]; // около ста элементов

Какой подход будет уместен для разделения (чункования) этого массива на множество меньших массивов, каждый из которых содержит не более 10 элементов?

5 ответ(ов)

3

Вот версия на ES6, использующая метод reduce для дробления массива на чанки:

const perChunk = 2; // количество элементов в чанке    

const inputArray = ['a', 'b', 'c', 'd', 'e'];

const result = inputArray.reduce((resultArray, item, index) => { 
  const chunkIndex = Math.floor(index / perChunk);

  if (!resultArray[chunkIndex]) {
    resultArray[chunkIndex] = []; // начинаем новый чанк
  }

  resultArray[chunkIndex].push(item);

  return resultArray;
}, []);

console.log(result); // результат: [['a','b'], ['c','d'], ['e']]

Массив inputArray остается неизменным, и вы можете легко увеличивать функциональность, добавляя цепочку других методов map или reduce.


Если вы предпочитаете более короткий, но менее читаемый вариант, можно использовать concat, чтобы добиться того же результата:

inputArray.reduce((all, one, i) => {
   const ch = Math.floor(i / perChunk); 
   all[ch] = [].concat((all[ch] || []), one); 
   return all;
}, []);

Также можно использовать оператор остатка, чтобы помещать последовательные элементы в разные чанки:

const ch = (i % perChunk); 

Таким образом, есть несколько подходов к решению этой задачи в JavaScript.

1

Чтобы разбить массив на чанки размером n с использованием генераторов в JavaScript, вы можете использовать следующий код:

function* chunks(arr, n) {
  for (let i = 0; i < arr.length; i += n) {
    yield arr.slice(i, i + n);
  }
}

let someArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log([...chunks(someArray, 2)]); // [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]

Этот код определяет функцию-генератор chunks, которая принимает массив и размер чанка, возвращая генератор, который производит подмассивы.

Для использования с TypeScript можно добавить типизацию следующим образом:

function* chunks<T>(arr: T[], n: number): Generator<T[], void> {
  for (let i = 0; i < arr.length; i += n) {
    yield arr.slice(i, i + n);
  }
}

Здесь мы добавили дженерик <T>, который позволяет функции работать с массивами любого типа. Таким образом, вы получите типизированный генератор, возвращающий подмассивы заданного типа T.

1

Для того чтобы разделить массив на части с использованием ES6, можно воспользоваться методом splice() в сочетании с учетом размера чанка. Вот как это можно сделать:

let [list, chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6];
list = [...Array(Math.ceil(list.length / chunkSize))].map(_ => list.splice(0, chunkSize));
console.log(list);

В этом коде мы сначала вычисляем, сколько частей нам нужно, используя Math.ceil(list.length / chunkSize), чтобы получить округленное вверх значение. Затем мы создаем новый массив, состоящий из этих частей, где каждый элемент — это результат выполнения list.splice(0, chunkSize), который извлекает chunkSize элементов из оригинального массива list.

В результате, console.log(list) выведет массив массивов, где каждый подмассив содержит элементы оригинального массива размером не больше заданного chunkSize.

Замечание: Использование splice модифицирует исходный массив list, поэтому если вам нужно сохранить его в неизменном виде, лучше использовать фильтрацию или другие методы, такие как slice.

0

Я протестировал различные варианты на jsperf.com. Результаты доступны по следующей ссылке: https://web.archive.org/web/20150909134228/https://jsperf.com/chunk-mtds.

Самая быстрая функция (которая также работает с IE8) выглядит следующим образом:

function chunk(arr, chunkSize) {
  if (chunkSize <= 0) throw "Invalid chunk size";
  var R = [];
  for (var i=0,len=arr.length; i<len; i+=chunkSize)
    R.push(arr.slice(i,i+chunkSize));
  return R;
}

Также стоит отметить, что функция может выдавать ошибку, если размер чанка не положителен.

0

В настоящее время вы можете использовать функцию chunk из библиотеки Lodash, чтобы разбить массив на более мелкие массивы. Документацию можно найти по следующей ссылке: https://lodash.com/docs#chunk. Больше нет необходимости заморачиваться с циклами!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь