어레이를 청크로 분할하다
예를 들어 다음과 같은 Javascript 배열이 있다고 합시다.
["Element 1","Element 2","Element 3",...]; // with close to a hundred elements.
예를 들어 최대 10개의 요소를 가진 다수의 소규모 어레이로 어레이를 청크(분할)하는 방법은 무엇입니까?
이 메서드는 원래 어레이를 변경하지 않고 어레이의 처음, 중간 또는 끝에서 필요한 용도로 슬라이스를 추출할 수 있습니다.
const chunkSize = 10;
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
// do whatever
}
★★★★chunk 수 chunkSize예를 들어, 다음과 같은 경우array 중 첫요소를 , 두 청크는 2.12개의요소만을 .
과 같습니다.chunkSize0무한 루프가 발생합니다.
다음은 reduce를 사용하는 ES6 버전입니다.
const perChunk = 2 // items per chunk
const inputArray = ['a','b','c','d','e']
const result = inputArray.reduce((resultArray, item, index) => {
const chunkIndex = Math.floor(index/perChunk)
if(!resultArray[chunkIndex]) {
resultArray[chunkIndex] = [] // start a new chunk
}
resultArray[chunkIndex].push(item)
return resultArray
}, [])
console.log(result); // result: [['a','b'], ['c','d'], ['e']]
또한 추가적인 지도 변환/축소도 가능합니다.입력 어레이는 그대로입니다.
어려운 버전이 몇 가지 수 .concat같은 최종 결과를 얻기 위해 혼합물을 사용합니다.
inputArray.reduce((all,one,i) => {
const ch = Math.floor(i/perChunk);
all[ch] = [].concat((all[ch]||[]),one);
return all
}, [])
나머지 연산자를 사용하여 연속된 항목을 다른 청크로 넣을 수 있습니다.
const ch = (i % perChunk);
dbaseman의 답변에서 수정: https://stackoverflow.com/a/10456344/711085
Object.defineProperty(Array.prototype, 'chunk_inefficient', {
value: function(chunkSize) {
var array = this;
return [].concat.apply([],
array.map(function(elem, i) {
return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
})
);
}
});
console.log(
[1, 2, 3, 4, 5, 6, 7].chunk_inefficient(3)
)
// [[1, 2, 3], [4, 5, 6], [7]]
마이너 부록:
는 그렇게 않은이라는 .Array.map는 기본적으로 ~는 다음과 같은 작업을 수행합니다.
[[1,2,3]]~[]~[]~[] ~ [[4,5,6]]~[]~[]~[] ~ [[7]]
이 값은 아래 방법과 점근적 실행 시간이 동일하지만 빈 목록을 작성하기 때문에 더 나쁜 상수 계수를 가질 수 있습니다.다음과 같이 고쳐 쓸 수 있습니다(대부분 Blazemonger의 메서드와 동일하기 때문에 이 답변을 원래 제출하지 않았습니다).
보다 효율적인 방법:
// refresh page if experimenting and you already defined Array.prototype.chunk
Object.defineProperty(Array.prototype, 'chunk', {
value: function(chunkSize) {
var R = [];
for (var i = 0; i < this.length; i += chunkSize)
R.push(this.slice(i, i + chunkSize));
return R;
}
});
console.log(
[1, 2, 3, 4, 5, 6, 7].chunk(3)
)
현재 제가 선호하는 방법은 위의 방법 또는 다음 중 하나입니다.
Array.range = function(n) {
// Array.range(5) --> [0,1,2,3,4]
return Array.apply(null,Array(n)).map((x,i) => i)
};
Object.defineProperty(Array.prototype, 'chunk', {
value: function(n) {
// ACTUAL CODE FOR CHUNKING ARRAY:
return Array.range(Math.ceil(this.length/n)).map((x,i) => this.slice(i*n,i*n+n));
}
});
데모:
> JSON.stringify( Array.range(10).chunk(3) );
[[1,2,3],[4,5,6],[7,8,9],[10]]
또는 Array.range 함수가 필요 없는 경우, 실제로는 1개의 라인(fluff 제외)에 불과합니다.
var ceil = Math.ceil;
Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
return Array(ceil(this.length/n)).fill().map((_,i) => this.slice(i*n,i*n+n));
}});
또는
Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
return Array.from(Array(ceil(this.length/n)), (_,i)=>this.slice(i*n,i*n+n));
}});
다음을 포함한 네이티브 프로토타입에 오염되지 않도록 하십시오.Array.prototype누가 코드를 소비할지 모르는 경우(서드파티, 동료, 나중에 자기 자신 등).
프로토타입을 안전하게 확장하는 방법(모든 브라우저는 아님)과 확장된 프로토타입을 사용하여 생성된 객체를 안전하게 소비하는 방법이 있지만, 더 나은 경험적 규칙은 '최소 놀라움' 원칙을 따르고 이러한 관행을 완전히 피하는 것입니다.
시간이 있으면 Andrew Dupont의 JSConf 2011 토크 "Everything is Permitted: 빌트인 확장"을 참조하십시오.
그러나 위의 솔루션은 작동하지만 지나치게 복잡하여 불필요한 계산 오버헤드가 필요합니다.저의 솔루션은 다음과 같습니다.
function chunk (arr, len) {
var chunks = [],
i = 0,
n = arr.length;
while (i < n) {
chunks.push(arr.slice(i, i += len));
}
return chunks;
}
// Optionally, you can do the following to avoid cluttering the global namespace:
Array.chunk = chunk;
제너레이터 사용
function* chunks(arr, n) {
for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n);
}
}
let someArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log([...chunks(someArray, 2)]) // [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
다른 답변을 jsperf.com에 테스트했습니다.결과는, https://web.archive.org/web/20150909134228/https 에서 입수할 수 있습니다.
그리고 가장 빠른 기능(IE8에서 작동)은 다음과 같습니다.
function chunk(arr, chunkSize) {
if (chunkSize <= 0) throw "Invalid chunk size";
var R = [];
for (var i=0,len=arr.length; i<len; i+=chunkSize)
R.push(arr.slice(i,i+chunkSize));
return R;
}
ECMA 6의 원라이너
const [list,chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6]
[...Array(Math.ceil(list.length / chunkSize))].map(_ => list.splice(0,chunkSize))
스플라이스 방법을 사용하는 것이 좋습니다.
var chunks = function(array, size) {
var results = [];
while (array.length) {
results.push(array.splice(0, size));
}
return results;
};
현재는 lodash' 청크 기능을 사용하여 어레이를 작은 어레이로 분할할 수 있습니다.https://lodash.com/docs#chunk 더 이상 루프를 조작할 필요가 없습니다.
오래된 질문:새로운 대답!나는 사실 이 질문의 답을 가지고 작업하고 있었는데 친구가 그것을 개선해 주었어요!여기 있습니다.
Array.prototype.chunk = function ( n ) {
if ( !this.length ) {
return [];
}
return [ this.slice( 0, n ) ].concat( this.slice(n).chunk(n) );
};
[1,2,3,4,5,6,7,8,9,0].chunk(3);
> [[1,2,3],[4,5,6],[7,8,9],[0]]
많은 답변이 있었지만 저는 다음과 같이 대답합니다.
const chunk = (arr, size) =>
arr
.reduce((acc, _, i) =>
(i % size)
? acc
: [...acc, arr.slice(i, i + size)]
, [])
// USAGE
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chunk(numbers, 3)
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
먼저 인덱스를 청크 크기로 나눌 때 나머지를 확인합니다.
나머지가 있는 경우는, 어큐뮬레이터 어레이를 반환합니다.
나머지가 없는 경우 인덱스는 청크 크기로 나눌 수 있으므로 원래 배열에서 슬라이스(현재 인덱스부터 시작)를 가져와 어큐뮬레이터 배열에 추가합니다.
reduce를 반복할 때마다 반환되는 어큐뮬레이터 어레이는 다음과 같습니다.
// 0: [[1, 2, 3]]
// 1: [[1, 2, 3]]
// 2: [[1, 2, 3]]
// 3: [[1, 2, 3], [4, 5, 6]]
// 4: [[1, 2, 3], [4, 5, 6]]
// 5: [[1, 2, 3], [4, 5, 6]]
// 6: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 7: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 8: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 9: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
다음 방법을 사용하여 하나 더 해결:
const chunk = (array, size) =>
array.reduce((acc, _, i) => {
if (i % size === 0) acc.push(array.slice(i, i + size))
return acc
}, [])
// Usage:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const chunked = chunk(numbers, 3)
console.log(chunked)
이 솔루션은 Steve Holgado의 솔루션과 매우 유사합니다.그러나 이 솔루션은 어레이 확산을 사용하지 않고 리듀서 기능에 새로운 어레이를 생성하지 않기 때문에 다른 솔루션보다 빠르고(jsPerf 테스트 참조), 주관적으로 읽기(심플한 구문)가 가능합니다.
모든 n번째 반복(여기서 n =size첫), 어레이(; ), 어레이acc됩니다().array.slice(i, i + size) )을(를 반환했습니다).을 사용하다다른 반복에서는 어큐뮬레이터 어레이가 그대로 반환됩니다.
ifsize이 경우 메서드는 빈 배열을 반환합니다. ifsize음수입니다. 메서드는 끊어진 결과를 반환합니다.필요한 , 이거나 긍정적이지 않은 경우, 이거나 긍정적이지 않은 , 조치를 취할 .size★★★★★★ 。
가 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」for가 더 수 .reduce()(jSPerf 테스트 참조) 및 일부에서는 이 스타일이 더 읽기 쉽다는 것을 알 수 있습니다.
function chunk(array, size) {
// This prevents infinite loops
if (size < 1) throw new Error('Size must be positive')
const result = []
for (let i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size))
}
return result
}
이것은 ES6 구문을 사용한 훌륭한 재귀 솔루션이라고 생각합니다.
const chunk = function(array, size) {
if (!array.length) {
return [];
}
const head = array.slice(0, size);
const tail = array.slice(size);
return [head, ...chunk(tail, size)];
};
console.log(chunk([1,2,3], 2));
좋아, 아주 엄격한 것부터 시작해보자.
function chunk(arr, n) {
return arr.slice(0,(arr.length+n-1)/n|0).
map(function(c,i) { return arr.slice(n*i,n*i+n); });
}
이것은 다음과 같이 사용됩니다.
chunk([1,2,3,4,5,6,7], 2);
그리고 다음과 같은 엄격한 리듀서 기능이 있습니다.
function chunker(p, c, i) {
(p[i/this|0] = p[i/this|0] || []).push(c);
return p;
}
이것은 다음과 같이 사용됩니다.
[1,2,3,4,5,6,7].reduce(chunker.bind(3),[]);
는 this이데올로기 때문에
// Fluent alternative API without prototype hacks.
function chunker(n) {
return function(p, c, i) {
(p[i/n|0] = p[i/n|0] || []).push(c);
return p;
};
}
이것은 다음과 같이 사용됩니다.
[1,2,3,4,5,6,7].reduce(chunker(3),[]);
그리고 이 모든 것을 한 번에 처리할 수 있는 매우 엄격한 기능도 있습니다.
function chunk(arr, n) {
return arr.reduce(function(p, cur, i) {
(p[i/n|0] = p[i/n|0] || []).push(cur);
return p;
},[]);
}
chunk([1,2,3,4,5,6,7], 3);
원라이너
const chunk = (a,n)=>[...Array(Math.ceil(a.length/n))].map((_,i)=>a.slice(n*i,n+n*i));
TypeScript의 경우
const chunk = <T>(arr: T[], size: number): T[][] =>
[...Array(Math.ceil(arr.length / size))].map((_, i) =>
arr.slice(size * i, size + size * i)
);
데모
const chunk = (a,n)=>[...Array(Math.ceil(a.length/n))].map((_,i)=>a.slice(n*i,n+n*i));
document.write(JSON.stringify(chunk([1, 2, 3, 4], 2)));
그룹 수별 청크
const part=(a,n)=>[...Array(n)].map((_,i)=>a.slice(i*Math.ceil(a.length/n),(i+1)*Math.ceil(a.length/n)));
TypeScript의 경우
const part = <T>(a: T[], n: number): T[][] => {
const b = Math.ceil(a.length / n);
return [...Array(n)].map((_, i) => a.slice(i * b, (i + 1) * b));
};
데모
const part = (a, n) => {
const b = Math.ceil(a.length / n);
return [...Array(n)].map((_, i) => a.slice(i * b, (i + 1) * b));
};
document.write(JSON.stringify(part([1, 2, 3, 4, 5, 6], 2))+'<br/>');
document.write(JSON.stringify(part([1, 2, 3, 4, 5, 6, 7], 2)));
순수 ES6에서 간단한 변이 없는 용액을 만드는 것을 목표로 했습니다.javascript의 특징은 매핑하기 전에 빈 배열을 채워야 한다는 것입니다.
function chunk(a, l) {
return new Array(Math.ceil(a.length / l)).fill(0)
.map((_, n) => a.slice(n*l, n*l + l));
}
재귀 기능이 있는 이 버전은 더 단순하고 매력적으로 보입니다.
function chunk(a, l) {
if (a.length == 0) return [];
else return [a.slice(0, l)].concat(chunk(a.slice(l), l));
}
ES6의 배열 기능이 터무니없이 약하기 때문에 좋은 퍼즐을 만들 수 있습니다:-)
이 https://www.npmjs.com/package/array.chunk의 npm 패키지를 작성했습니다.
var result = [];
for (var i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, size + i));
}
return result;
Typeed Array 사용 시
var result = [];
for (var i = 0; i < arr.length; i += size) {
result.push(arr.subarray(i, size + i));
}
return result;
「」를 사용합니다.Array.prototype.splice()이치노
Array.prototype.chunk = function(size) {
let result = [];
while(this.length) {
result.push(this.splice(0, size));
}
return result;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.chunk(2));
갱신하다
Array.prototype.splice()를 채우고, 「」를 한 에 입력합니다.chunk()의 배열원래의 배열)arr가 됩니다.[].
변경하지 않고 합니다.arr데이터를 다른 어레이로 변환하고 동일한 작업을 수행합니다.
Array.prototype.chunk = function(size) {
let data = [...this];
let result = [];
while(data.length) {
result.push(data.splice(0, size));
}
return result;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log('chunked:', arr.chunk(2));
console.log('original', arr);
추신: @mts-knn님 감사합니다.
다음 ES2015 접근법은 함수를 정의할 필요 없이 익명 배열에서 직접 작동합니다(청크 크기 2의 예).
[11,22,33,44,55].map((_, i, all) => all.slice(2*i, 2*i+2)).filter(x=>x.length)
이에 대한 함수를 정의하려면 다음과 같이 할 수 있습니다(K에서 개선).Blazemonger의 답변에 대한 코멘트:
const array_chunks = (array, chunk_size) => array
.map((_, i, all) => all.slice(i*chunk_size, (i+1)*chunk_size))
.filter(x => x.length)
> 5. EcmaScript의 버전을 구현할 수 .chunk()O(N) 복잡도의 array.reduce()를 사용합니다.
function chunk(chunkSize, array) {
return array.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 ||
previous[previous.length -1].length === chunkSize) {
chunk = []; // 1
previous.push(chunk); // 2
}
else {
chunk = previous[previous.length -1]; // 3
}
chunk.push(current); // 4
return previous; // 5
}, []); // 6
}
console.log(chunk(2, ['a', 'b', 'c', 'd', 'e']));
// prints [ [ 'a', 'b' ], [ 'c', 'd' ], [ 'e' ] ]
설명// nbr 개요:
- 값청크의 있는 경우 가 " " ( " : " " ) " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
chunkSize - 기존 청크의 배열에 새 청크를 추가합니다.
- 그렇지 않으면 현재 청크가 청크 배열의 마지막 청크가 됩니다.
- 청크에 현재 값 추가
- 수정된 청크 배열 반환
- 빈 어레이를 전달하여 절감 초기화
chunkSize:
var chunk3 = function(array) {
return chunk(3, array);
};
console.log(chunk3(['a', 'b', 'c', 'd', 'e']));
// prints [ [ 'a', 'b', 'c' ], [ 'd', 'e' ] ]
를 추가할 수 있습니다.chunk()글로벌하게 기능하다Array오브젝트:
Object.defineProperty(Array.prototype, 'chunk', {
value: function(chunkSize) {
return this.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 ||
previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []);
}
});
console.log(['a', 'b', 'c', 'd', 'e'].chunk(4));
// prints [ [ 'a', 'b', 'c' 'd' ], [ 'e' ] ]
js
function splitToBulks(arr, bulkSize = 20) {
const bulks = [];
for (let i = 0; i < Math.ceil(arr.length / bulkSize); i++) {
bulks.push(arr.slice(i * bulkSize, (i + 1) * bulkSize));
}
return bulks;
}
console.log(splitToBulks([1, 2, 3, 4, 5, 6, 7], 3));
타이프 스크립트
function splitToBulks<T>(arr: T[], bulkSize: number = 20): T[][] {
const bulks: T[][] = [];
for (let i = 0; i < Math.ceil(arr.length / bulkSize); i++) {
bulks.push(arr.slice(i * bulkSize, (i + 1) * bulkSize));
}
return bulks;
}
results = []
chunk_size = 10
while(array.length > 0){
results.push(array.splice(0, chunk_size))
}
순수한 Javascript의 한 줄:
function chunks(array, size) {
return Array.apply(0,{length: Math.ceil(array.length / size)}).map((_, index) => array.slice(index*size, (index+1)*size))
}
// The following will group letters of the alphabet by 4
console.log(chunks([...Array(26)].map((x,i)=>String.fromCharCode(i + 97)), 4))
lodash 사용을 추천합니다.청킹은 많은 유용한 기능 중 하나입니다.순서:
npm i --save lodash
프로젝트에 포함:
import * as _ from 'lodash';
사용방법:
const arrayOfElements = ["Element 1","Element 2","Element 3", "Element 4", "Element 5","Element 6","Element 7","Element 8","Element 9","Element 10","Element 11","Element 12"]
const chunkedElements = _.chunk(arrayOfElements, 10)
샘플은 https://playcode.io/659171/ 에서 찾을 수 있습니다.
이 예에서는 어레이를 2개의 요소로 이루어진 청크로 분할합니다.단, 원래 어레이가 비워질 때까지 어레이에서 청크를 스플라이스합니다.
const array = [86,133,87,133,88,133,89,133,90,133];
const new_array = [];
const chunksize = 2;
while (array.length) {
const chunk = array.splice(0,chunksize);
new_array.push(chunk);
}
console.log(new_array)
Array.protype.reduce 함수를 사용하여 한 줄로 이 작업을 수행할 수 있습니다.
let arr = [1,2,3,4];
function chunk(arr, size)
{
let result = arr.reduce((rows, key, index) => (index % size == 0 ? rows.push([key]) : rows[rows.length-1].push(key)) && rows, []);
return result;
}
console.log(chunk(arr,2));
그리고 이것이 이 주제에 대한 저의 기여가 될 것입니다.그런 것 같다..reduce()가장 좋은 방법입니다.
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);
res = segment(arr,7);
console.log(JSON.stringify(res));
그러나 위의 구현은 매우 효율적이지 않습니다..reduce() arr(은 축소된는) 하는 것입니다.그 이유는 에 어레이의 계산해 둘 수 있기 때문입니다.이러한 접근법은 다음과 같은 방법으로 어레이의 크기를 미리 계산할 수 있기 때문입니다.Math.ceil(arr/n);다음과 같은 빈 결과 배열이 생성되면Array(Math.ceil(arr.length/n)).fill();나머지는 슬라이스를 매핑하는 것입니다.arr열합니니다다
function chunk(arr,n){
var r = Array(Math.ceil(arr.length/n)).fill();
return r.map((e,i) => arr.slice(i*n, i*n+n));
}
arr = Array.from({length: 31},(_,i) => i+1);
res = chunk(arr,7);
console.log(JSON.stringify(res));
지금까지는 양호하지만 위의 스니펫을 더욱 단순화할 수 있습니다.
var chunk = (a,n) => Array.from({length: Math.ceil(a.length/n)}, (_,i) => a.slice(i*n, i*n+n)),
arr = Array.from({length: 31},(_,i) => i+1),
res = chunk(arr,7);
console.log(JSON.stringify(res));
in coffeescript:
b = (a.splice(0, len) while a.length)
demo
a = [1, 2, 3, 4, 5, 6, 7]
b = (a.splice(0, 2) while a.length)
[ [ 1, 2 ],
[ 3, 4 ],
[ 5, 6 ],
[ 7 ] ]
lodash의 청크 사용
lodash.chunk(arr,<size>).forEach(chunk=>{
console.log(chunk);
})
const array = ['a', 'b', 'c', 'd', 'e'];
const size = 2;
const chunks = [];
while (array.length) {
chunks.push(array.splice(0, size));
}
console.log(chunks);
언급URL : https://stackoverflow.com/questions/8495687/split-array-into-chunks
'programing' 카테고리의 다른 글
| phpmyadmin 오류 해결 방법 (0) | 2022.09.08 |
|---|---|
| bash 스크립트가 MariaDB 서비스 상태를 올바르게 제공하지 않음 (0) | 2022.09.06 |
| Python non local 문 (0) | 2022.09.06 |
| GSON과의 JSON 해석 중 Enum 사용 (0) | 2022.09.06 |
| mysql에서 문자열을 플로트로 변환하려면 어떻게 해야 하나요? (0) | 2022.09.06 |