Cara membagi array panjang menjadi array yang lebih kecil, dengan JavaScript

100

Saya memiliki serangkaian email (bisa hanya 1 email, atau 100 email), dan saya perlu mengirim array dengan permintaan ajax (yang saya tahu bagaimana melakukannya), tetapi saya hanya dapat mengirim array yang memiliki 10 atau kurang e-mail di dalamnya. Jadi jika ada array asli dari 20 email, saya perlu membaginya menjadi 2 array yang masing-masing terdiri dari 10. atau jika ada 15 email dalam array asli, kemudian 1 array 10, dan array lain 5. Saya menggunakan jQuery, apa cara terbaik untuk melakukan ini?

Tagihan
sumber

Jawaban:

195

Jangan gunakan jquery ... gunakan javascript biasa

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];

Anda dapat mengulang ini untuk mendapatkan perilaku yang Anda inginkan.

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

Ini akan memberi Anda 10 elemen sekaligus ... jika Anda mengatakan 15 elemen, Anda akan mendapatkan 1-10, 11-15 seperti yang Anda inginkan.

jyore
sumber
9
Perhatikan bahwa YOUR_ARRAY akan digunakan juga (array adalah objek ...)
Claudio
Ya, saya baru saja meletakkannya karena a tidak deskriptif, dan saya sudah menulis contoh menggunakan ... itu adalah baris kode yang sama sekali tidak perlu ... Meskipun, itu membuat saya berpikir ... jika menggunakan pola ini, Anda mungkin ingin melakukan deep copy ke dalam array kerja agar tidak mengganggu Anda yang asli
jyore
@junvar IDK jika 1-liner itu berfungsi pada tahun 2018 (saya benar-benar meragukannya), tetapi gagal total hari ini. Anda tidak boleh mengubah (yaitu menghapus elemen) sebuah array yang sedang diiterasi, itu membuang indeks, yaitu setelah setiap penghapusan itu harus disesuaikan kembali dengan jumlah elemen yang dihapus, sehingga "melompat ke depan" dan tidak mengkonsumsi array seluruhnya. Cobalah
Drew Reese
107
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
     arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);

Tidak seperti splice(), slice()tidak merusak array asli.

Blazemonger
sumber
1
solusi ini lebih baik
Maduekwe Pedro
38

Cukup putar ulang array, sambungkan hingga semua habis.



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

while (a.length > 0) {

  chunk = a.splice(0,3)

  console.log(chunk)

}

keluaran


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

Claudio
sumber
33

Anda dapat menggunakan lodash: https://lodash.com/docs

_.chunk(['a', 'b', 'c', 'd'], 2);
// → [['a', 'b'], ['c', 'd']]
Alexander Paramonov
sumber
13

Dengan asumsi Anda tidak ingin menghancurkan array asli, Anda dapat menggunakan kode seperti ini untuk memecah array panjang menjadi array yang lebih kecil yang kemudian dapat Anda iterasi:

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
}
jfriend00
sumber
6

Implementasi lain:

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 - Ini tidak mengubah larik asli.

Atau, jika Anda lebih suka metode fungsional, 100% tidak dapat diubah (meskipun sebenarnya tidak ada hal buruk dalam bermutasi di tempat seperti yang dilakukan di atas) dan metode mandiri:

function splitBy(size, list) {
  return list.reduce((acc, curr, i, self) => {
    if ( !(i % size)  ) {  
      return [
          ...acc,
          self.slice(i, i + size),
        ];
    }
    return acc;
  }, []);
}
Aurelio
sumber
5

Sebagai pelengkap jawaban @ jyore , dan jika Anda masih ingin menyimpan array asli:

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];
Justin
sumber
5

Array.reduce bisa jadi tidak efisien untuk array besar, terutama dengan operator mod. Saya pikir solusi fungsional yang lebih bersih (dan mungkin lebih mudah dibaca) adalah ini:

const chunkArray = (arr, size) =>
  arr.length > size
    ? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)]
    : [arr];
tawnos178
sumber
3

Metode lain:

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]];

Ini tidak mempengaruhi array asli karena salinan, dibuat menggunakan slice, diteruskan ke argumen peta 'ini'.

AFurlepa
sumber
3

Saya ingin membagikan solusi saya juga. Ini sedikit lebih bertele-tele tetapi berfungsi juga.

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);

Output (diformat):

[ [ 1,  2,  3,  4],
  [ 5,  6,  7,  8],
  [ 9, 10, 11, 12],
  [13, 14, 15    ] ]
Filipe Nicoli
sumber
2

Implementasi lain, menggunakan Array.reduce (saya pikir itu satu-satunya yang hilang!):

const splitArray = (arr, size) =>
{
    if (size === 0) {
        return [];
    }

    return arr.reduce((split, element, index) => {
        index % size === 0 ? split.push([element]) : split[Math.floor(index / size)].push(element);
        return split;
    }, []);
};

Seperti banyak solusi di atas, solusi yang satu ini tidak merusak. Mengembalikan array kosong ketika ukurannya 0 hanyalah konvensi. Jika ifpemblokiran dihilangkan, Anda mendapatkan kesalahan, yang mungkin Anda inginkan.

Alf
sumber
1

Anda dapat melihat kode ini. Sederhana dan Efektif.

function chunkArrayInGroups(array, unit) {
var results = [],
length = Math.ceil(array.length / unit);

for (var i = 0; i < length; i++) {
    results.push(array.slice(i * unit, (i + 1) * unit));
}
 return results;
}

chunkArrayInGroups(["a", "b", "c", "d"], 2);
Subhankar
sumber
1

Ini adalah satu baris sederhana

var segment = (arr, n) => arr.reduce((r,e,i) => i%n ? (r[r.length-1].push(e), r)
                                                    : (r.push([e]), r), []),
        arr = Array.from({length: 31}).map((_,i) => i+1);
console.log(segment(arr,7));

Redu
sumber
1

Lebih kompak:

const chunk = (xs, size) =>
  xs.map((_, i) =>
    (i % size === 0 ? xs.slice(i, i + size) : null)).filter(Boolean);
    
// Usage:
const sampleArray = new Array(33).fill(undefined).map((_, i) => i);

console.log(chunk(sampleArray, 5));

dzuc
sumber
0

Jika Anda menginginkan metode yang tidak mengubah array yang ada, coba ini:

let oldArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
let newArray = [];
let size = 3; // Size of chunks you are after
let j = 0; // This helps us keep track of the child arrays

for (var i = 0; i < oldArray.length; i++) {
  if (i % size === 0) {
    j++
  }
  if(!newArray[j]) newArray[j] = [];
  newArray[j].push(oldArray[i])
}
Ryan
sumber
0
function chunkArrayInGroups(arr, size) {
    var newArr=[];

    for (var i=0; arr.length>size; i++){
    newArr.push(arr.splice(0,size));
    }
    newArr.push(arr.slice(0));
    return newArr;

}

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);
zgthompson.dll
sumber
jangan lupa untuk membuat: newArr = [] variabel lokal
zgthompson
Jawaban Hanya Kode cenderung ditandai dan kemudian dihapus karena Kualitas Rendah. Bisakah Anda memberikan beberapa komentar tentang bagaimana ini memecahkan masalah aslinya?
Graham
ini tidak berfungsi jika ukuran potongan lebih kecil dari ukuran larik input.
r3wt
0
function chunkArrayInGroups(arr, size) {
    var newArr=[];

    for (var i=0; i < arr.length; i+= size){
    newArr.push(arr.slice(i,i+size));
    }
    return newArr;

}

chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6], 3);
Ridwanullah Ibrahim
sumber
2
Selamat datang di stackoverflow. Jawaban Anda akan ditingkatkan dengan menambahkan beberapa penjelasan.
Simon.SA
0

sebagai suatu fungsi

var arrayChunk = function (array, chunkSize) {
            var arrayOfArrays = [];

            if (array.length <= chunkSize) {
                arrayOfArrays.push(array);
            } else {
                for (var i=0; i<array.length; i+=chunkSize) {
                    arrayOfArrays.push(array.slice(i,i+chunkSize));
                }
            }
            return arrayOfArrays;
        }

menggunakan

arrayChunk(originalArray, 10) //10 being the chunk size.
Clint
sumber
0

menggunakan rekursi

let myArr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
let size = 4; //Math.sqrt(myArr.length); --> For a n x n matrix
let tempArr = [];
function createMatrix(arr, i) {
    if (arr.length !== 0) {
      if(i % size == 0) {
        tempArr.push(arr.splice(0,size))
      } 
      createMatrix(arr, i - 1)
    }
}
createMatrix(myArr, myArr.length);
console.log(tempArr);

Catatan: Array yang ada yaitu myArr akan dimodifikasi.

Siddharth Yadav
sumber
0

menggunakan prototipe kita dapat mengatur langsung ke kelas array

Array.prototype.chunk = function(n) {
  if (!this.length) {
    return [];
  }
  return [this.slice(0, n)].concat(this.slice(n).chunk(n));
};
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].chunk(5));

AmitNayek
sumber
0
const originalArr = [1,2,3,4,5,6,7,8,9,10,11];
const splittedArray = [];
  while (originalArr.length > 0) {
    splittedArray.push(originalArr.splice(0,range));  
  }

keluaran untuk rentang 3

splittedArray === [[1,2,3][4,5,6][7,8,9][10,11]]

keluaran untuk rentang 4

splittedArray === [[1,2,3,4][5,6,7,8][9,10,11]]
Haures Bogdan
sumber
Bisakah Anda menambahkan beberapa deskripsi?
ego