Разбить массив на куски - PullRequest
       163

Разбить массив на куски

396 голосов
/ 14 декабря 2011

Допустим, у меня есть массив Javascript, который выглядит следующим образом:

["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.

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

Ответы [ 46 ]

1 голос
/ 29 сентября 2017

Для функционального решения используйте Рамда :

Где popularProducts - ваш входной массив, 5 - размер чанка

import splitEvery from 'ramda/src/splitEvery'

splitEvery(5, popularProducts).map((chunk, i) => {
// do something with chunk

})
1 голос
/ 26 июня 2019

Вот рекурсивное решение, оптимизирующее хвостовой вызов.

const splitEvery = (n, xs, y=[]) =>
  xs.length===0 ? y : splitEvery(n, xs.slice(n), y.concat([xs.slice(0, n)])) 

console.log(splitEvery(2, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
1 голос
/ 25 мая 2016

Я только что написал это с помощью функции groupBy.

// utils
const group = (source) => ({
  by: (grouping) => {
    const groups = source.reduce((accumulator, item) => {
      const name = JSON.stringify(grouping(item));
      accumulator[name] = accumulator[name] || [];
      accumulator[name].push(item);
      return accumulator;
    }, {});

    return Object.keys(groups).map(key => groups[key]);
  }
});

const chunk = (source, size) => group(source.map((item, index) => ({ item, index })))
.by(x => Math.floor(x.index / size))
.map(x => x.map(v => v.item));


// 103 items
const arr = [6,2,6,6,0,7,4,9,3,1,9,6,1,2,7,8,3,3,4,6,8,7,6,9,3,6,3,5,0,9,3,7,0,4,1,9,7,5,7,4,3,4,8,9,0,5,1,0,0,8,0,5,8,3,2,5,6,9,0,0,1,5,1,7,0,6,1,6,8,4,9,8,9,1,6,5,4,9,1,6,6,1,8,3,5,5,7,0,8,3,1,7,1,1,7,6,4,9,7,0,5,1,0];

const chunks = chunk(arr, 10);

console.log(JSON.stringify(chunks));
1 голос
/ 07 августа 2018

Это должен быть простой ответ без многих математических сложностей.

function chunkArray(array, sizeOfTheChunkedArray) {
  const chunked = [];

  for (let element of array) {
    const last = chunked[chunked.length - 1];

    if(!last || last.length === sizeOfTheChunkedArray) {
      chunked.push([element])
    } else {
      last.push(element);
    }
  }
  return chunked;
}
1 голос
/ 29 августа 2018

Привет, попробуй это -

 function split(arr, howMany) {
        var newArr = []; start = 0; end = howMany;
        for(var i=1; i<= Math.ceil(arr.length / howMany); i++) {
            newArr.push(arr.slice(start, end));
            start = start + howMany;
            end = end + howMany
        }
        console.log(newArr)
    }
    split([1,2,3,4,55,6,7,8,8,9],3)
0 голосов
/ 17 апреля 2019

Мой трюк заключается в использовании parseInt(i/chunkSize) и parseInt(i%chunkSize), а затем заполнении массива

// filling items
let array = [];
for(let i = 0; i< 543; i++)
  array.push(i);
 
 // printing the splitted array
 console.log(getSplittedArray(array, 50));
 
 // get the splitted array
 function getSplittedArray(array, chunkSize){
  let chunkedArray = [];
  for(let i = 0; i<array.length; i++){
    try{
      chunkedArray[parseInt(i/chunkSize)][parseInt(i%chunkSize)] = array[i];
    }catch(e){
      chunkedArray[parseInt(i/chunkSize)] = [];
      chunkedArray[parseInt(i/chunkSize)][parseInt(i%chunkSize)] = array[i];
    }
  }
  return chunkedArray;
 }
0 голосов
/ 12 августа 2016

Хорошо, хорошая функция для этого была бы:

function chunk(arr,times){
    if(times===null){var times = 10} //Fallback for users wanting to use the default of ten
   var tempArray = Array() //Array to be populated with chunks
    for(i=0;i<arr.length/times;i++){
     tempArray[i] = Array() //Sub-Arrays        //Repeats for each chunk         
   for(j=0;j<times;j++){
        if(!(arr[i*times+j]===undefined)){tempArray[i][j] = arr[i*times+j]//Populate Sub-  Arrays with chunks
    }
     else{
       j = times //Stop loop
       i = arr.length/times //Stop loop
  }
    }
     }
   return tempArray //Return the populated and chunked array
   }

Использование было бы:

chunk(array,sizeOfChunks)

Я прокомментировал это, чтобы вы могли понять, что происходит.

(форматирование немного отключено, я запрограммировал это на мобильном телефоне)

0 голосов
/ 17 октября 2016
Array.prototype.sliceIntoChunks = function(chunkSize) {
                    var chunks = [];
                    var temparray = null;

                    for (var i = 0; i < this.length; i++) {
                        if (i % chunkSize === 0) {
                            temparray = new Array();
                            chunks.push(temparray);
                        }
                        temparray.push(this[i]);
                    }

                    return chunks;
                };

Вы можете использовать следующим образом:

var myArray = ["A", "B", "C", "D", "E"];
var mySlicedArray = myArray.sliceIntoChunks(2);

Результат:

mySlicedArray[0] = ["A", "B"];
mySlicedArray[1] = ["C", "D"];
mySlicedArray[2] = ["E"];
0 голосов
/ 16 июля 2015
# in coffeescript
# assume "ar" is the original array
# newAr is the new array of arrays

newAr = []
chunk = 10
for i in [0... ar.length] by chunk
   newAr.push ar[i... i+chunk]

# or, print out the elements one line per chunk
for i in [0... ar.length] by chunk
   console.log ar[i... i+chunk].join ' '
0 голосов
/ 07 ноября 2016

Вот решение с использованием ImmutableJS, где items - неизменный список, а size - требуемый размер группировки.

const partition = ((items, size) => {
  return items.groupBy((items, i) => Math.floor(i/size))
})
...