숙박업소나 서비스 평가처럼 여러 기준별 점수를 담고 있는 객체가 있다고 가정해 보겠습니다.
const rating = {
'overall': 92,
'atmosphere': 93,
'cleanliness': 94,
'facilities': 89,
'staff': 94,
'security': 92,
'location': 88,
'valueForMoney': 92
}이 글에서는 이러한 객체를 인수로 받아 가장 큰 값을 가진 키-값 쌍을 반환하는 JavaScript 함수를 작성하는 방법을 알아보겠습니다.
예를 들어 위 객체라면 최댓값은 94이므로 결과는 다음과 같은 형태가 되어야 합니다.
const output = {
'staff': 94
};풀이 접근 방법
문제 해결 과정은 다음 세 단계로 정리할 수 있습니다.
Object.values()메서드로 객체의 모든 값을 배열 형태로 추출합니다.Math.max.apply()(또는 스프레드 문법)를 사용해 배열에서 최댓값을 구합니다.for...in루프로 객체를 순회하며 최댓값과 일치하는 첫 번째 키를 찾아 해당 키-값 쌍을 객체로 반환합니다.
예제 코드
const rating = {
'overall': 92,
'atmosphere': 93,
'cleanliness': 94,
'facilities': 89,
'staff': 94,
'security': 92,
'location': 88,
'valueForMoney': 92
};
const findHighest = obj => {
const values = Object.values(obj);
const max = Math.max.apply(Math, values);
for (const key in obj) {
if (obj[key] === max) {
return { [key]: max };
}
}
};
console.log(findHighest(rating));실행 결과
콘솔에는 다음과 같이 출력됩니다.
{ cleanliness: 94 }왜 staff가 아니라 cleanliness일까요? 이 객체에는 94점인 항목이 두 개(cleanliness, staff) 있습니다. for...in 루프는 객체에 정의된 순서대로 순회하기 때문에 먼저 만나는 cleanliness가 반환됩니다. 즉, 최댓값이 여러 개일 경우 이 함수는 그중 첫 번째 항목 하나만 반환한다는 점을 유의해야 합니다.
더 간결한 대안: reduce 활용
ES6 이상 환경이라면 Object.entries()와 reduce()를 조합해 코드를 훨씬 간결하게 만들 수도 있습니다.
const findHighest = obj => Object.entries(obj).reduce((a, b) => (b[1] > a[1] ? b : a)); console.log(findHighest(rating)); // ['cleanliness', 94]
이 방식은 임시 변수 없이 비교 로직만으로 최댓값 항목을 찾아내므로 코드가 짧고 가독성도 좋습니다. 필요하다면 반환된 배열을 Object.fromEntries()로 감싸 객체 형태로 변환할 수도 있습니다.