So teilen Sie ein langes Array mit JavaScript in kleinere Arrays auf

91

Ich habe ein Array von E-Mails (es kann nur 1 E-Mail oder 100 E-Mails sein), und ich muss das Array mit einer Ajax-Anfrage senden (die ich zu tun weiß), aber ich kann nur ein Array senden, das hat 10 oder weniger E-Mails darin. Wenn es also ein Original-Array mit 20 E-Mails gibt, muss ich sie in 2 Arrays mit jeweils 10 E-Mails aufteilen. oder wenn das ursprüngliche Array 15 E-Mails enthält, dann 1 Array mit 10 und ein weiteres Array mit 5. Ich verwende jQuery. Was wäre der beste Weg, dies zu tun?

Rechnung
quelle

Antworten:

187

Verwenden Sie keine jquery ... verwenden Sie einfaches 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];

Sie können dies in einer Schleife ausführen, um das gewünschte Verhalten zu erzielen.

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

Dies würde Ihnen 10 Elemente gleichzeitig geben ... Wenn Sie 15 Elemente sagen, erhalten Sie 1-10, die 11-15, wie Sie wollten.

jyore
quelle
9
Beachten Sie, dass YOUR_ARRAY ebenfalls verbraucht wird (Array sind Objekte ...)
Claudio
Ja, ich habe das nur gesagt, weil a nicht beschreibend ist, und ich habe das Beispiel bereits mit a geschrieben ... es ist eine völlig unnötige Codezeile ... obwohl das mich denken lässt ... wenn ich dieses Muster verwende, Vielleicht möchten Sie eine tiefe Kopie in ein funktionierendes Array
erstellen,
@junvar IDK, wenn dieser 1-Liner im Jahr 2018 funktioniert hat (ich bezweifle ernsthaft, dass dies der Fall war), aber er scheitert heute kläglich. Sie sollten niemals ein Array mutieren (dh Elemente entfernen), über das iteriert wird. Es wirft den Index ab, dh nach jedem Entfernen sollte es um die Anzahl der entfernten Elemente neu angepasst werden, damit es "überspringt" und das nicht verbraucht Array vollständig. Probieren Sie es aus
Drew Reese
104
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
     arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);

Im Gegensatz splice(), slice()ist zerstörungsfrei zu der ursprünglichen Anordnung.

Blazemonger
quelle
37

Durchlaufen Sie einfach das Array und spleißen Sie es, bis alles verbraucht ist.



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

while (a.length > 0) {

  chunk = a.splice(0,3)

  console.log(chunk)

}

Ausgabe


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

Claudio
quelle
33

Sie können lodash verwenden: https://lodash.com/docs

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

Angenommen, Sie möchten das ursprüngliche Array nicht zerstören, können Sie Code wie diesen verwenden, um das lange Array in kleinere Arrays aufzuteilen, über die Sie dann iterieren können:

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
quelle
6

Eine weitere Implementierung:

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 - Das ursprüngliche Array wird dadurch nicht geändert.

Oder, wenn Sie eine funktionale, 100% unveränderliche (obwohl es wirklich nichts Schlechtes ist, an Ort und Stelle zu mutieren, wie oben beschrieben) und eigenständige Methode bevorzugen:

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

Als Ergänzung zu @ jyores Antwort und für den Fall, dass Sie das ursprüngliche Array beibehalten möchten:

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
quelle
4

Array.reduce kann für große Arrays ineffizient sein, insbesondere mit dem Mod-Operator. Ich denke, eine sauberere (und möglicherweise leichter zu lesende) funktionale Lösung wäre folgende:

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

Eine andere Methode:

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

Dies wirkt sich nicht auf das ursprüngliche Array aus, da eine mit Slice erstellte Kopie an das Argument 'this' der Karte übergeben wird.

AFurlepa
quelle
3

Ich möchte auch meine Lösung teilen. Es ist etwas ausführlicher, funktioniert aber auch.

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

Ausgabe (formatiert):

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

Eine weitere Implementierung mit Array.reduce (ich denke, es ist die einzige, die fehlt!):

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

Wie viele Lösungen oben, ist dies zerstörungsfrei. Das Zurückgeben eines leeren Arrays bei einer Größe von 0 ist nur eine Konvention. Wenn der ifBlock weggelassen wird, wird eine Fehlermeldung angezeigt, die möglicherweise Ihren Wünschen entspricht.

Alf
quelle
1

Sie können sich diesen Code ansehen. Einfach und effektiv.

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
quelle
1

Hier ist ein einfacher Einzeiler

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

Reduzieren
quelle
1

Kompakter:

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
quelle
0

Wenn Sie eine Methode wünschen, die das vorhandene Array nicht ändert, versuchen Sie Folgendes:

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
quelle
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
quelle
Vergessen Sie nicht zu machen: newArr = [] eine lokale Variable
zgthompson
Nur-Code-Antworten werden in der Regel markiert und dann gelöscht, weil sie von geringer Qualität sind. Könnten Sie einen Kommentar dazu abgeben, wie dies das ursprüngliche Problem löst?
Graham
Dies funktioniert nicht, wenn die Blockgröße kleiner als die Größe des Eingabearrays ist.
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
quelle
2
Willkommen beim Stackoverflow. Ihre Antwort würde durch Hinzufügen einer Erklärung verbessert.
Simon.SA
0

als eine Funktion

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

benutzen

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

mit Rekursion

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

Hinweis: Das vorhandene Array, dh myArr, wird geändert.

Siddharth Yadav
quelle
0

Mit dem Prototyp können wir direkt auf die Array-Klasse setzen

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
quelle