Lodash를 사용하여 자바 스크립트 배열을 청크로 분할


83

JavaScript 배열을 n크기가 지정된 청크 로 분할해야합니다 .

예 : 주어진 배열

["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"]

a n가 4이면 출력은 다음과 같아야합니다.

[ ["a1", "a2", "a3", "a4"],
  ["a5", "a6", "a7", "a8"],
  ["a9", "a10", "a11", "a12"],
  ["a13"]
]

이 문제에 대한 순수한 JavaScript 솔루션 을 알고 있지만 이미 Lodash를 사용하고 있기 때문에 Lodash가 이에 대한 더 나은 솔루션을 제공하는지 궁금합니다.

편집하다:

밑줄 솔루션이 얼마나 느린 지 확인하기 위해 jsPerf 테스트 를 만들었습니다 .

답변:


126

lodash의 청크를 살펴보세요 : https://lodash.com/docs#chunk

const data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
const chunks = _.chunk(data, 3);
console.log(chunks);
// [
//  ["a1", "a2", "a3"],
//  ["a4", "a5", "a6"],
//  ["a7", "a8", "a9"],
//  ["a10", "a11", "a12"],
//  ["a13"]
// ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


lodash와 하위 호환 API 모두에 밑줄을 긋는 것이 도움이 될 것입니다.
Jonno_FTW

@Jonah 사실입니다. 이전의 대답은 그러므로 나는 :) 독자를 위해 허용 대답을 업데이트하지 이상 최고의 하나입니다
세자르 Canassa

90

Underscore 기반 솔루션의 경우 다음을 시도하십시오.

var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.groupBy(data, function(element, index){
  return Math.floor(index/n);
});
lists = _.toArray(lists); //Added this to convert the returned object to an array.
console.log(lists);

체인 래퍼 방법을 사용하면 다음과 같이 두 문을 결합 할 수 있습니다.

var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.chain(data).groupBy(function(element, index){
  return Math.floor(index/n);
}).toArray()
.value();

1
이상하게도 Underscore 는 배열이 아닌 groupBy 객체를 반환합니다 . 딜 브레이커는 아닙니다. 기본적으로 동일한 기능을 제공하지만 약간의 의미가 있습니다. 편집 : 오, 체인 성을 유지하기 위해 그렇게합니다. 여전히 흥미 롭습니다.
Jordan Running

@Cesar Canassa : 해당 코드를 읽는 미래의 개발자를 위해 많이 사용할 경우 사용자 지정 라이브러리에 함수로 넣거나 사용하지 않을 경우 잘 주석 처리하는 것이 좋습니다. :)
Briguy37

@Jordan : 그것을 깨닫지 못했습니다. 객체를 배열로 수렴하는 답변을 편집했습니다.
Chandu

나는 그것이 가장 잘하는 일에 Underscore를 사용하고 (그리고 OP는 Underscore 기반 솔루션을 요청했기 때문에 는 과분하지 않습니다) 기능적 솔루션의 경우이 솔루션이 많은 오버 헤드를 도입하는 것처럼 보입니다. @ ajax33321이 지적했듯이 splice루프는 여전히 3 줄이며 훨씬 더 성능이 좋습니다. 어레이가 짧으면 문제가되지 않지만 수백 또는 수천 개의 항목을 처리하는 경우 성능을 주시하십시오.
Jordan Running

1
이것은 더 이상 최선의 해결책이 아닙니다. 대신 chunk ()를 사용하십시오
Jonah

4

더 간단한 표현 :

const coll = [ "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9" ];
const n = 2;
const chunks = _.range(coll.length / n).map(i => coll.slice(i * n, (i + 1) * n));
console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


1
무엇보다 간단합니까? 답변은 단독으로해야합니다.
Nathan Tuggy 2015 년

4

밑줄은 1.9.0 버전부터 기본적으로 _.chunk ()를 지원합니다 .

const data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
const chunks = _.chunk(data, 4);
console.log(chunks);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>


1

이것을 시도하는 것이 훨씬 더 실용적입니다 (예를 들어, 각 하위 배열의 컨테이너가 될 항목의 양에 따라 배열을 분할하려는 경우).

function chunk(arr, start, amount){
    var result = [], 
        i, 
        start = start || 0, 
        amount = amount || 500, 
        len = arr.length;

    do {
        //console.log('appending ', start, '-', start + amount, 'of ', len, '.');
        result.push(arr.slice(start, start+amount));
        start += amount;

    } while (start< len);

    return result;
};

귀하의 경우에 사용 :

var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
    chunked = chunk(arr, 0, Math.floor(arr.length/3)); //to get 4 nested arrays

console.log(chunked);

다른 경우 :

var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
    chunked = chunk(arr, 0, 3); // to get 6 nested arrays each containing maximum of 3 items

console.log(chunked);

start매개 변수는 실제적인 imho가 아닙니다. 일반적으로 통과하고 싶지 않습니다. 하지만 항상 청크 크기를 지정해야합니다. 이 두 매개 변수를 더 잘 교체하십시오.
Bergi

이것이 do while루프 인 이유는 무엇 입니까? 아무도 빈 청크를 원하지 않습니다.
Bergi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.