Как разбить длинный массив на меньшие массивы с помощью JavaScript - PullRequest
64 голосов
/ 01 сентября 2011

У меня есть массив электронных писем (это может быть только 1 электронное письмо или 100 электронных писем), и мне нужно отправить массив с запросом ajax (что я знаю, как сделать), но я могу только отправитьмассив, который содержит 10 или менее электронных писем.Поэтому, если существует оригинальный массив из 20 электронных писем, мне нужно будет разделить их на 2 массива по 10 в каждом.или если в исходном массиве 15 электронных писем, то 1 массив из 10 и другой массив из 5. Я использую jQuery, что будет лучшим способом сделать это?

Ответы [ 16 ]

143 голосов
/ 01 сентября 2011

Не используйте jquery ... используйте обычный javascript

var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

var b = a.splice(0,10);

//a is now [11,12,13,14,15];
//b is now [1,2,3,4,5,6,7,8,9,10];

Вы можете зациклить это, чтобы получить желаемое поведение.

var a = YOUR_ARRAY;
while(a.length) {
    console.log(a.splice(0,10));
}

Это даст вам 10 элементов ввремя ... если вы скажете 15 элементов, вы получите 1-10, 11-15, как хотели.

77 голосов
/ 01 сентября 2011
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
     arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);

В отличие от splice(), slice() не разрушает исходный массив.

26 голосов
/ 07 апреля 2015

Вы можете использовать lodash: https://lodash.com/docs

_.chunk(['a', 'b', 'c', 'd'], 2);
// → [['a', 'b'], ['c', 'd']]
26 голосов
/ 01 сентября 2011

Просто зациклите массив, объединяя его, пока он не будет полностью использован.



var a = ['a','b','c','d','e','f','g']
  , chunk

while (a.length > 0) {

  chunk = a.splice(0,3)

  console.log(chunk)

}

выход


[ 'a', 'b', 'c' ]
[ 'd', 'e', 'f' ]
[ 'g' ]

10 голосов
/ 01 сентября 2011

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

var longArray = [];   // assume this has 100 or more email addresses in it
var shortArrays = [], i, len;

for (i = 0, len = longArray.length; i < len; i += 10) {
    shortArrays.push(longArray.slice(i, i + 10));
}

// now you can iterate over shortArrays which is an 
// array of arrays where each array has 10 or fewer 
// of the original email addresses in it

for (i = 0, len = shortArrays.length; i < len; i++) {
    // shortArrays[i] is an array of email addresss of 10 or less
}
5 голосов
/ 30 ноября 2014

В качестве дополнения к @ jyore's answer , и если вы все еще хотите сохранить исходный массив:

var originalArray = [1,2,3,4,5,6,7,8];

var splitArray = function (arr, size) {

  var arr2 = arr.slice(0),
      arrays = [];

  while (arr2.length > 0) {
      arrays.push(arr2.splice(0, size));
  }

  return arrays;
}

splitArray(originalArray, 2);
// originalArray is still = [1,2,3,4,5,6,7,8];
3 голосов
/ 27 октября 2017

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

var data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

var chunksize = 4;


var chunks = [];

data.forEach((item)=>{
  if(!chunks.length || chunks[chunks.length-1].length == chunksize)
  chunks.push([]);

  chunks[chunks.length-1].push(item);
});

console.log(chunks);

Вывод (в формате):

[ [ 1,  2,  3,  4],
  [ 5,  6,  7,  8],
  [ 9, 10, 11, 12],
  [13, 14, 15    ] ]
3 голосов
/ 08 марта 2017

Другой метод:

var longArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var size = 2;

var newArray = new Array(Math.ceil(longArray.length / size)).fill("")
    .map(function() { return this.splice(0, size) }, longArray.slice());

// newArray = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]];

Это не влияет на исходный массив, поскольку копия, сделанная с использованием среза, передается в аргумент 'this' карты.

3 голосов
/ 01 октября 2016

Другая реализация:

const arr = ["H", "o", "w", " ", "t", "o", " ", "s", "p", "l", "i", "t", " ", "a", " ", "l", "o", "n", "g", " ", "a", "r", "r", "a", "y", " ", "i", "n", "t", "o", " ", "s", "m", "a", "l", "l", "e", "r", " ", "a", "r", "r", "a", "y", "s", ",", " ", "w", "i", "t", "h", " ", "J", "a", "v", "a", "S", "c", "r", "i", "p", "t"];

const size = 3; 
const res = arr.reduce((acc, curr, i) => {
  if ( !(i % size)  ) {    // if index is 0 or can be divided by the `size`...
    acc.push(arr.slice(i, i + size));   // ..push a chunk of the original array to the accumulator
  }
  return acc;
}, []);

// => [["H", "o", "w"], [" ", "t", "o"], [" ", "s", "p"], ["l", "i", "t"], [" ", "a", " "], ["l", "o", "n"], ["g", " ", "a"], ["r", "r", "a"], ["y", " ", "i"], ["n", "t", "o"], [" ", "s", "m"], ["a", "l", "l"], ["e", "r", " "], ["a", "r", "r"], ["a", "y", "s"], [",", " ", "w"], ["i", "t", "h"], [" ", "J", "a"], ["v", "a", "S"], ["c", "r", "i"], ["p", "t"]]

NB - Это не изменяет исходный массив.

Или, если вы предпочитаете функциональный, неизменный и автономный метод:

function splitBy(size, list) {
  return list.reduce((acc, curr, i, self) => {
    if ( !(i % size)  ) {  
      return [
          ...acc,
          self.slice(i, i + size),
        ];
    }
    return acc;
  }, []);
}
1 голос
/ 03 января 2019

Array.reduce может быть неэффективным для больших массивов, особенно с оператором модов.Я думаю, что более чистое (и, возможно, более удобное для чтения) функциональное решение будет следующим:

const chunkArray = (arr, size) =>
  arr.length > size
    ? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)]
    : [arr];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...