Javascript - Array groupBy() 함수 사용법

이번에는 Javascript의 Array가 가진 groupBy() 함수의 정의와 사용 방법에 대해 알아보겠습니다. groupBy() 함수는 알아두면 컬렉션(Collection)을 다룰 때 유용하게 쓸 수 있기 때문에 기본적인 사용 방법뿐만 아니라 알아두면 활용하는 부분도 예제 코드로 확인해보겠습니다. 그리고 자바의 스트림 API에서도 groupBy() 기능을 사용할 수 있어요.

groupBy() 정의

Array.prototype.groupBy ( callbackfn[, thisArg] )

 MDN에서 groupBy() 함수는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다고 정의합니다. 조금 말이 어렵다고 생각되는데요. groupBy() 함수가 주로 사용되는 용도를 보면 배열의 값을 묶거나 분류할 때 활용할 수 있는 함수입니다. 구체적인 사용 방법은 예제 코드로 대신하겠습니다.

const numbers = [1, 2, 2, 3, 3, 3];
const result = numbers.groupBy(number => number);

console.log(result);
// 1: Array [ 1 ]
// 2: Array [ 2, 2 ]
// 3: Array(3) [ 3, 3, 3 ]

 예제 코드는 주어진 숫자들을 groupBy()를 사용해 묶는 코드입니다. callbackfn의 인자로 묶는 조건식을 전달하면 전달한 식에 맞추어 그룹화된 목록을 반환합니다. for문과 같은 반복문, if 구문을 사용하지 않고도 groupBy() 함수를 사용하면 손쉽게 값들을 그룹화할 수 있습니다. 

 

 또한 groupBy() 함수의 경우 현재 지원하는 브라우저가 firefox- Nightly 뿐이기 때문에 underscore나 lodash 같은 별도의 자바스크립트 라이브러리를 추가해야지만 사용할 수 있습니다.

groupBy() 지원 브라우저 목록 - MDN

 

groupBy() 사용법

 groupBy()를 사용하는 방법은 callbackfn을 통해 주어지는 3개의 인자(요소 값, index, 순회하는 대상 객체)를 사용해 새로운 값을 만드는 함수를 등록하는 것입니다.

const numbers = [1, 2, 2, 3, 3, 3];
const result = numbers.groupBy((value, index, source) => {
  // value: 요소값
  // index: source에서 요소의 index
  // source: 순회하는 대상
  
  console.log(value); // 1
  console.log(index);  // 0
  console.log(source); // [1, 2, 2, 3, 3, 3]
  return value;
});

callbackfn을 통해 사용할 수 있는 값도 중요하지만 groupBy()에서 중요한 포인트는 반환 값입니다. callbackfn의 반환 값은 그룹화할 때 사용되는 구분 값입니다. 반환 값이 구분을 짓는 기준을 결정하기 때문에 어떤 값을 구분 값으로 사용하느냐에 따라 groupBy()의 결과가 달라집니다. 그렇기 때문에 groupBy()를 잘 사용하는 방법은 이 기준 값을 어떻게 사용하느냐에 따라 달려 있습니다.

groupBy() 활용법

- JSON key 값으로 그룹화

const goods = [
  { name: "desktop", price: 1000 },
  { name: "laptop", price: 1000 },
  { name: "mouse", price: 100 },
  { name: "keyboard", price: 120 },
  { name: "monitor", price: 500 },
];

console.log(goods.groupBy(({price}) => price));

// 100: Array [ {…} ]
// 120: Array [ {…} ]
// 500: Array [ {…} ]
// 1000: Array [ {…}, {…} ]

 JSON은 데이터를 표현하는 포맷입니다. 자바스크립트에서 데이터를 다룰 때는 JSON을 주로 사용하는데 JSON 객체도 groupBy()를 사용하면 예제 코드처럼 그룹화를 시킬 수 있습니다.

- 프로퍼티(Property)를 사용한 그룹화

console.log(["하나", "둘", "셋"].groupBy(({length}) => length));

// 1: Array [ "둘", "셋" ]
// 2: Array [ "하나" ]

 객체가 가진 값 중에 프로퍼티를 사용해도 그룹화를 시킬 수 있습니다. 예시로 문자가 가진 속성(Property) 중 length를 사용해서 그룹핑하는 코드를 작성해보았습니다. 객체가 가진 모든 것은 분류의 기준이 될 수 있습니다.

- 함수(Function)를 사용한 그룹화

console.log([9.8, 7.1, 9.2].groupBy(Math.floor));

// 7: Array [ 7.1 ]
// 9: Array [ 9.8, 9.2 ]

 groupBy()는 식을 인자로 전달받습니다. 다르게 말하면 매번 함수를 정의해서 전달하지 않아도 정의된 함수를 구분하는 식으로 사용할 수 있다는 이야기입니다. 예를 들면 Math.floor()과 같이 정의되어 있는 함수를 활용할 수 있습니다.

- 새로운 구분 값을 정의하는 방법

const goods = [
  { name: "desktop", price: 1000 },
  { name: "laptop", price: 1000 },
  { name: "mouse", price: 100 },
  { name: "keyboard", price: 120 },
  { name: "monitor", price: 500 },
];

console.log(goods.groupBy(({ price }) => (price < 500 ? "buy" : "can't buy")));

// "buy": Array [ {…}, {…} ]
// "can't buy": Array(3) [ {…}, {…}, {…} ]

 groupBy() 함수의 재미있는 점은 구분 값을 재정의 할 수 있다는 부분입니다. 객체가 가지고 있는 어떤 값을 사용할 수 있는 동시에 구분 값은 새롭게 정의할 수 있습니다. 즉 구분 값을 자유롭게 정의할 수 있고 이는 예제 코드처럼 결과의 묶음 값도 편의에 따라 정의할 수 있습니다. 마치 filter()처럼 말이죠.

groupBy() 함수 만들기

const groupBy = (data, predicate) => {
  return data.reduce((result, value) => {
    let group = value[predicate];

    if ("function" === typeof predicate) {
      group = predicate(value);
    }

    if (result[group] === undefined) {
      result[group] = [];
    }

    result[group].push(value);
    return result;
  }, {});
};

console.log(groupBy(goods, "price"));

console.log(groupBy(["하나", "둘", "셋"], "length"));
console.log(groupBy([9.8, 7.1, 9.2], Math.floor));

console.log(groupBy(goods, ({ price }) => (price < 500 ? "buy" : "can't buy")));

 자바스크립트 라이브러리를 사용해서 groupBy()를 사용하는 것도 좋지만 코드를 구현해보는 것만큼 좋은 학습 방법도 없기 때문에 직접 groupBy() 함수를 작성해보았습니다. 그룹화 조건은 key를 이용해 객체의 특정 값을 사용하거나 함수를 인자로 받아 사용할 수 있도록 정의하였습니다. groupBy() 사양은 링크를 통해 확인해보세요.

 

 글에서 사용한 코드는 첨부파일로도 제공합니다. 필요하신 분은 다운로드해서 사용해보세요.

groupBy_sample.html
0.00MB

반응형

댓글

Designed by JB FACTORY