Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 객체 배열을 배열 객체로 변환하는 방법

팀에 대한 데이터가 객체 배열(array of objects) 형태로 주어져 있고, 이를 역할(role)을 키(key)로, 해당 역할의 선수 이름 배열을 값(value)으로 갖는 하나의 객체(object of arrays)로 변환해야 하는 상황을 가정해 보겠습니다.

샘플 데이터

변환 대상이 되는 샘플 배열은 다음과 같습니다.

const team = [{
    role: 'Batsman',
    player: 'V Kohli'
}, {
    role: 'Wicket Keeper',
    player: 'KL Rahul'
}, {
    role: 'Batsman',
    player: 'R Sharma'
}, {
    role: 'Wicket Keeper',
    player: 'R Pant'
}, {
    role: 'Bowler',
    player: 'B Kumar'
}, {
    role: 'Bowler',
    player: 'M Shami'
}]

objectify() 함수 구현

배열을 인자로 받아 그에 대응하는 객체를 반환하는 objectify() 함수를 정의해 보겠습니다.

const objectify = (team) => {
    const teamObject = {};
    team.forEach(member => {
        if(teamObject[member.role]){
            teamObject[member.role].push(member.player);
        }else{
            teamObject[member.role] = [member.player];
        }
    });
    return teamObject;
}
console.log(objectify(team));

동작 원리는 간단합니다. 배열의 각 항목을 하나씩 순회하면서, 해당 역할이 이미 teamObject에 존재하면 그 역할의 배열에 선수를 추가(push)하고, 존재하지 않으면 선수 한 명을 담은 새로운 배열을 할당합니다.

전체 코드

const team = [{
    role: 'Batsman',
    player: 'V Kohli'
}, {
    role: 'Wicket Keeper',
    player: 'KL Rahul'
}, {
    role: 'Batsman',
    player: 'R Sharma'
}, {
    role: 'Wicket Keeper',
    player: 'R Pant'
}, {
    role: 'Bowler',
    player: 'B Kumar'
}, {
    role: 'Bowler',
    player: 'M Shami'
}]

const objectify = (team) => {
    const teamObject = {};
    team.forEach(member => {
        if(teamObject[member.role]){
            teamObject[member.role].push(member.player);
        }else{
            teamObject[member.role] = [member.player];
        }
    });
    return teamObject;
}

console.log(objectify(team));

출력 결과

콘솔에서 실행한 결과는 다음과 같습니다.

{
    Batsman: [ 'V Kohli', 'R Sharma' ],
    WicketKeeper: [ 'KL Rahul', 'R Pant' ],
    Bowler: [ 'B Kumar', 'M Shami' ]
}

대안: reduce() 활용하기

forEach 대신 reduce() 메서드를 사용하면 같은 로직을 더 간결하게 표현할 수 있습니다.

const objectify = (team) =>
    team.reduce((acc, { role, player }) => {
        (acc[role] = acc[role] || []).push(player);
        return acc;
    }, {});

acc[role] = acc[role] || [] 패턴은 해당 역할의 배열이 아직 없을 때 빈 배열을 먼저 만들어 줍니다. 덕분에 조건문 없이도 안전하게 선수를 추가할 수 있으며, 코드가 한층 깔끔해집니다.