Mam tablicę e-maili (może to być tylko 1 e-mail lub 100 e-maili) i muszę wysłać tablicę z żądaniem ajax (które wiem, jak to zrobić), ale mogę wysłać tylko tablicę, która ma Zawiera 10 lub mniej e-maili. Więc jeśli istnieje oryginalna tablica 20 e-maili, będę musiała podzielić je na 2 tablice po 10 każda. lub jeśli w oryginalnej tablicy jest 15 e-maili, to 1 tablica 10 i druga tablica 5. Używam jQuery, jaki byłby najlepszy sposób na zrobienie tego?
javascript
jquery
arrays
loops
Rachunek
źródło
źródło
var size = 10; var arrayOfArrays = []; for (var i=0; i<bigarray.length; i+=size) { arrayOfArrays.push(bigarray.slice(i,i+size)); } console.log(arrayOfArrays);
W przeciwieństwie
splice()
,slice()
jest nieinwazyjne do oryginalnej tablicy.źródło
Po prostu zapętl tablicę, łącząc ją, aż zostanie zużyta.
var a = ['a','b','c','d','e','f','g'] , chunk while (a.length > 0) { chunk = a.splice(0,3) console.log(chunk) }
wynik
[ 'a', 'b', 'c' ] [ 'd', 'e', 'f' ] [ 'g' ]
źródło
Możesz skorzystać z lodash: https://lodash.com/docs
_.chunk(['a', 'b', 'c', 'd'], 2); // → [['a', 'b'], ['c', 'd']]
źródło
Zakładając, że nie chcesz niszczyć oryginalnej tablicy, możesz użyć takiego kodu, aby podzielić długą tablicę na mniejsze tablice, które możesz następnie powtórzyć:
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 }
źródło
Array.reduce może być nieefektywne w przypadku dużych tablic, szczególnie w przypadku operatora mod. Myślę, że czystszym (i prawdopodobnie łatwiejszym do odczytania) rozwiązaniem funkcjonalnym byłoby to:
const chunkArray = (arr, size) => arr.length > size ? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)] : [arr];
źródło
Kolejna realizacja:
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 - To nie zmienia oryginalnej tablicy.
Lub, jeśli wolisz funkcjonalną, w 100% niezmienną (chociaż nie ma nic złego w mutowaniu w miejscu, jak to zrobiono powyżej) i samodzielną metodą:
function splitBy(size, list) { return list.reduce((acc, curr, i, self) => { if ( !(i % size) ) { return [ ...acc, self.slice(i, i + size), ]; } return acc; }, []); }
źródło
Jako dodatek do użytkownika @ jyore odpowiedź , aw przypadku nadal chcesz zachować oryginalną tablicę:
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];
źródło
Chciałbym również podzielić się moim rozwiązaniem. Jest trochę bardziej szczegółowy, ale też działa.
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);
Wyjście (sformatowane):
[ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15 ] ]
źródło
Inna metoda:
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]];
Nie ma to wpływu na oryginalną tablicę, ponieważ kopia utworzona przy użyciu plasterka jest przekazywana do argumentu „this” mapy.
źródło
Kolejna implementacja, wykorzystująca Array.reduce (myślę, że to jedyna brakująca!):
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; }, []); };
Jak wiele rozwiązań powyżej, ten jest nieniszczący. Zwracanie pustej tablicy, gdy rozmiar wynosi 0, to tylko konwencja. Jeśli
if
blok zostanie pominięty, pojawi się błąd, który może być tym, czego chcesz.źródło
Możesz spojrzeć na ten kod. Prosty i skuteczny.
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);
źródło
Oto prosta jedna wkładka
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));
źródło
Bardziej kompaktowy:
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));
źródło
Jeśli potrzebujesz metody, która nie modyfikuje istniejącej tablicy, spróbuj tego:
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]) }
źródło
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);
źródło
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);
źródło
jako funkcja
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; }
używać
arrayChunk(originalArray, 10) //10 being the chunk size.
źródło
używając rekurencji
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);
Uwaga: istniejąca tablica, tj. MyArr, zostanie zmodyfikowana.
źródło
używając prototypu możemy ustawić bezpośrednio na klasę tablicową
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));
źródło
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)); }
wyjście dla zakresu 3
splittedArray === [[1,2,3][4,5,6][7,8,9][10,11]]
wyjście dla zakresu 4
splittedArray === [[1,2,3,4][5,6,7,8][9,10,11]]
źródło