JavaScript를 사용하여 긴 배열을 더 작은 배열로 분할하는 방법
일련의 전자 메일(1개의 전자 메일 또는 100개의 전자 메일)이 있으며, Ajax 요청(방법을 알고 있음)과 함께 어레이를 보내야 하지만 10개 이하의 전자 메일만 보낼 수 있습니다.따라서 20개의 이메일 원본 배열이 있다면 각각 10개씩 2개의 배열로 분할해야 합니다.또는 원래 배열에 15개의 전자 메일이 있는 경우 10개의 배열 중 하나와 5개의 배열이 있습니다.제가 jQuery를 사용하고 있는데, 어떤 방법이 가장 좋을까요?
jquery를 사용하지 마십시오.일반 자바스크립트를 사용합니다.
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];
원하는 동작을 얻기 위해 이것을 반복할 수 있습니다.
var a = YOUR_ARRAY;
while(a.length) {
console.log(a.splice(0,10));
}
이렇게 하면 한 번에 10개의 요소를 얻을 수 있습니다.만약 당신이 15개의 요소를 말한다면, 당신은 당신이 원하는 대로 1-10, 11-15를 얻을 것입니다.
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);
와는 달리 원래 배열에 손상을 주지 않습니다.
lodash: https://lodash.com/docs 를 사용할 수 있습니다.
_.chunk(['a', 'b', 'c', 'd'], 2);
// → [['a', 'b'], ['c', 'd']]
어레이를 루프하여 모두 사용될 때까지 스플라이싱합니다.
var a = ['a','b','c','d','e','f','g']
, chunk
while (a.length > 0) {
chunk = a.splice(0,3)
console.log(chunk)
}
산출량
[ 'a', 'b', 'c' ]
[ 'd', 'e', 'f' ]
[ 'g' ]
Array.reduce는 특히 mod 연산자를 사용하는 대규모 어레이에서는 비효율적일 수 있습니다.더 깨끗하고 읽기 쉬운 기능적인 솔루션은 다음과 같습니다.
const chunkArray = (arr, size) =>
arr.length > size
? [arr.slice(0, size), ...chunkArray(arr.slice(size), size)]
: [arr];
원래 어레이를 파괴하고 싶지 않다고 가정하면 다음과 같은 코드를 사용하여 긴 어레이를 더 작은 어레이로 분할한 다음 반복할 수 있습니다.
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
}
다른 구현:
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 - 원래 배열을 수정하지 않습니다.
또는 기능적이고 100% 불변(위와 같이 돌연변이를 일으키는 데 나쁜 점은 없지만) 및 자체 포함 방법을 선호하는 경우:
function splitBy(size, list) {
return list.reduce((acc, curr, i, self) => {
if ( !(i % size) ) {
return [
...acc,
self.slice(i, i + size),
];
}
return acc;
}, []);
}
@jyore의 답변에 대한 보충 자료로, 그리고 여전히 원래 배열을 유지하고 싶은 경우:
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];
저도 제 해결책을 공유하고 싶습니다.조금 더 장황하지만 효과도 있습니다.
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);
출력(포맷됨):
[ [ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15 ] ]
빈 배열로 시작하여 원래 배열에서 를 뺄 때까지 원래 배열에서 원하는 범위의 섹션을 안쪽으로 밀어넣을 수 있습니다.
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));
}
범위 3에 대한 출력
splittedArray === [[1,2,3][4,5,6][7,8,9][10,11]]
범위 4에 대한 출력
splittedArray === [[1,2,3,4][5,6,7,8][9,10,11]]
원하는 경우 전면 페이지에도 적합합니다.
ES6 생성기 사용
파티에 늦었지만 ES6 발전기는 요구되는 것을 달성하기 위한 또 다른 깔끔한 방법을 열었습니다.
/**
* Returns chunks of size n.
* @param {Array<any>} array any array
* @param {number} n size of chunk
*/
function* chunks(array, n){
for(let i = 0; i < array.length; i += n) yield array.slice(i, i + n);
}
const result = [...chunks([1, 2, 3, 4, 5, 6, 7, 8 , 9, 10], 3)];
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
무한 확장 발전기에서 작동 가능
한 아이디어를 의 동한아이사를용무여양한생있다수니를 생성할 수 를 만들 수 .n-sized
다른 생성기 함수에서 검색된 값의 청크입니다.이는 필요한 값을 느리게 생성하는 데 매우 유용하여 필요한 메모리를 크게 줄이거나 무한하거나 알 수 없는 수의 청크를 생성하는 데도 사용할 수 있습니다.
다음은 두 개의 발전기를 사용하는 예제입니다.
nextNaturalNumber()
는 항상 다음 자연수를 반환하는 무한 생성기입니다.저는 ES2020 데이터 유형을 사용하고 있으므로 값의 크기에 대한 제한이 없습니다(자바스크립트 기준).chunksFromIterable()
성n-sized
무한 반복 가능성이 있는 청크입니다.
/**
* Returns chunks of size n for a possibly infinite iterator.
* n must be >= 1
* @param {Iterable<any>} iterable any array
* @param {number} n size of chunk for n >= 1
*/
function* chunksFromIterable(iterable, n){
let arr = [];
let i = n;
for (const value of iterable) {
if(i <= 0) {
// another chunk of size n is filled => return chunk
yield arr;
arr = []; // create new empty array
i = n;
};
arr.push(value);
i--;
}
// in case the iterable is not infinite check if there are still values in the array and return them if necessary
if(arr.length > 0) yield arr;
}
/**
* Infinite iterator which always gets the next natural number.
*/
function* nextNaturalNumber(){
let i = 0n;
while(true) {
i += 1n;
yield i;
}
}
console.log("Finite iterable:");
// this version can now be used using the for ... of loop
for(const threeNaturalNumbers of chunksFromIterable([1, 2, 3, 4, 5, 6, 7, 8 , 9, 10], 3)){
console.log(threeNaturalNumbers);
}
console.log("Infinite iterable:");
// and it can also be used for this infinite generator
for(const threeNaturalNumbers of chunksFromIterable(nextNaturalNumber(), 3)){
printBigIntArray(threeNaturalNumbers);
if(threeNaturalNumbers[0] > 30) break; // end here to avoid an infinite loop
}
// helper function to print array of bigints as this does not seem to be working for snippets
function printBigIntArray(arr){
console.log(`[${arr.join(", ")}]`);
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
다른 방법:
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]];
슬라이스를 사용하여 만든 복사본이 맵의 'this' 인수로 전달되므로 원래 배열에는 영향을 주지 않습니다.
Array.reduce를 사용한 또 다른 구현(유일하게 누락된 것 같습니다!):
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;
}, []);
};
위의 많은 해결책들처럼, 이것은 파괴적이지 않습니다.크기가 0일 때 빈 배열을 반환하는 것은 관례일 뿐입니다.에 약에만.if
블록이 생략되었습니다. 오류가 발생하면 원하는 것일 수 있습니다.
더 컴팩트하게:
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));
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);
이 코드를 보시면 됩니다. 간단하고 효과적입니다.
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);
여기 간단한 라이너가 있습니다.
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));
함수로서
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;
}
사용할
arrayChunk(originalArray, 10) //10 being the chunk size.
재귀 사용
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);
참고: 기존 배열, 즉 myArr이 수정됩니다.
프로토타입을 사용하여 어레이 클래스로 직접 설정할 수 있습니다.
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));
let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
let size = 5;
let fragments = Array.from(Array(Math.ceil(a.length / size))).map((_,index) => a.slice(index * size,(index + 1) * size))
분할할 숫자 배열(numGroups)을 알고 있는 경우 아래 기능을 사용할 수 있습니다.
function createGroups(arr, numGroups) {
const perGroup = Math.ceil(arr.length / numGroups);
return new Array(numGroups)
.fill('')
.map((_, i) => arr.slice(i * perGroup, (i + 1) * perGroup));
}
샘플 사용:
createGroups([0, 1, 2, 3, 4, 5, 6], 3); //arr = [0, 1, 2, 3, 4, 5, 6] and numGroups = 3
기존 배열을 수정하지 않는 방법을 사용하려면 다음을 시도하십시오.
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])
}
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);
다음 코드를 사용하여 필요한 기능을 수행할 수 있습니다.
const splitter = (arr, splitBy, cache = []) => {
const tmp = [...arr]
while (tmp.length) cache.push(tmp.splice(0, splitBy))
return cache
}
const split = splitter([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21], 10)
console.log(split);
길이 22의 배열이었는데 분할기 함수는 10개의 항목으로 구성된 2개의 작은 배열과 2개의 항목으로 구성된 1개의 배열로 분할합니다.
let a = [1, 2, 3, 4, 6, 7, 8, 9, 10, 11];
let _splitCount = 3;
let b = a.reduce((acc, curr, index) => {
if (index % _splitCount === 0) {
acc.push([curr]);
} else {
acc[acc.length - 1].push(curr);
}
return acc;
}, []);
이것이 제가 생각하는 쉬운 해결책입니다❤️
map+filter를 대신 사용하여 다음을 줄일 수 있습니다.
a.map((x,i,a,chunk=3)=>i%chunk ? null: a.slice(i,i+chunk)).filter(x=>x)
언급URL : https://stackoverflow.com/questions/7273668/how-to-split-a-long-array-into-smaller-arrays-with-javascript
'programing' 카테고리의 다른 글
mysql5.5와 maria를 사용할 수 있습니까?동일한 시스템에 DB 10.0이 있습니까? (0) | 2023.09.02 |
---|---|
이러한 인라인 블록 디비 요소 사이에 설명할 수 없는 차이가 있는 이유는 무엇입니까? (0) | 2023.09.02 |
sqlite에서 문자열을 패딩과 연결하는 방법 (0) | 2023.09.02 |
인터셉트와 트랜스폼 리스폰스의 정확한 차이점은 무엇입니까? (0) | 2023.09.02 |
재료 설계 및 AppCompat을 사용하는 Android의 컬러링 버튼 (0) | 2023.09.02 |