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?

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.


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.


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



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
}

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

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

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

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.


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

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.


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

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


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


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

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

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

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.

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.


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.