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?

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.


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.


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



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
}

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;
  }, []);
}

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

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

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'.


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

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.


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

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


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


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])
}

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

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

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.

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.


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


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

Bisakah Anda menambahkan beberapa deskripsi?
ego
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.