JavaScript를 사용하여 긴 배열을 더 작은 배열로 분할하는 방법


100

전자 메일 배열이 있고 (단지 1 개 또는 100 개일 수 있음) ajax 요청 (방법을 알고 있음)과 함께 배열을 보내야하지만 다음이있는 배열 만 보낼 수 있습니다. 10 개 이하의 이메일이 있습니다. 따라서 원래 20 개의 전자 메일 배열이있는 경우 각각 10 개씩 2 개의 배열로 분할해야합니다. 또는 원래 배열에 15 개의 전자 메일이 있고 10 개의 배열과 5 개의 다른 배열이있는 경우 jQuery를 사용하고 있습니다.이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변:


195

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 개를 얻을 수 있습니다.


9
YOUR_ARRAY도 소비됩니다 (배열은 객체입니다 ...)
Claudio

예, 저는 a가 설명이 아니기 때문에 그것을 넣은 것입니다. 그리고 저는 이미 a를 사용하여 예제를 작성했습니다 ... 완전히 불필요한 코드 라인입니다 ...하지만 그것은 생각하게 만듭니다 ...이 패턴을 사용한다면, 원본을 방해하지 않도록 작업 배열에 딥 카피를 수행 할 수 있습니다.
jyore 2011-09-01

@junvar IDK가 2018 년에 1 라이너가 작동했다면 (진지하게 의심 스럽지만) 오늘은 비참하게 실패합니다. 반복되는 배열을 변경 (즉, 요소 ​​제거) 해서는 안됩니다 . 인덱스를 제거합니다. 즉, 제거 할 때마다 제거 된 요소 수에 따라 다시 조정되어야합니다. 따라서 "앞으로 건너 뛰고" 완전히 배열합니다. 시도해보세요
Drew Reese

107
var size = 10; var arrayOfArrays = [];
for (var i=0; i<bigarray.length; i+=size) {
     arrayOfArrays.push(bigarray.slice(i,i+size));
}
console.log(arrayOfArrays);

달리 splice(), slice()원래의 배열 비파괴이다.


1
이 솔루션이 더 좋습니다
Maduekwe Pedro

38

배열을 반복하여 모두 소모 될 때까지 연결합니다.



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



13

원래 배열을 파괴하고 싶지 않다고 가정하면 다음과 같은 코드를 사용하여 긴 배열을 더 작은 배열로 나눈 다음 반복 할 수 있습니다.

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

또 다른 구현 :

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

5

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

5

Array.reduce는 특히 mod 연산자의 경우 큰 배열의 경우 비효율적 일 수 있습니다. 더 깨끗한 (그리고 아마도 읽기 쉬운) 기능적 솔루션은 다음과 같습니다.

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

3

다른 방법 :

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

slice를 사용하여 만든 복사본이 map의 'this'인수로 전달되므로 원본 배열에는 영향을주지 않습니다.


3

내 솔루션도 공유하고 싶습니다. 좀 더 장황하지만 잘 작동합니다.

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

2

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블록이 생략 되면 원하는 오류가 발생합니다.


1

이 코드를 살펴볼 수 있습니다. 간단하고 효과적입니다.

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

여기에 간단한 한 라이너가 있습니다.

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

더 콤팩트 :

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

기존 배열을 수정하지 않는 방법을 원한다면 다음을 시도하십시오.

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

잊지 마세요 : newArr = [] 지역 변수
zgthompson

코드 전용 답변은 낮은 품질로 인해 플래그가 지정된 다음 삭제되는 경향이 있습니다. 이것이 원래 문제를 어떻게 해결하는지에 대한 설명을 제공 할 수 있습니까?
Graham

청크 크기가 입력 배열 크기보다 작 으면 작동하지 않습니다.
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
stackoverflow에 오신 것을 환영합니다. 몇 가지 설명을 추가하면 답변이 향상됩니다.
Simon.SA

0

함수로서

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.

0

재귀 사용

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이 수정됩니다.


0

프로토 타입을 사용하여 배열 클래스에 직접 설정할 수 있습니다.

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


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

설명을 추가해 주시겠습니까?
자아
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.