두 객체의 유사도를 백분율로 계산하는 방법
다음과 같은 두 개의 객체가 있다고 가정해 보겠습니다.
const a = {
Make: "Apple",
Model: "iPad",
hasScreen: "yes",
Review: "Great product!",
};
const b = {
Make: "Apple",
Model: "iPad",
waterResistant: false
};여기서 우리가 작성해야 할 함수는 두 객체에서 공통 속성(키와 값이 모두 동일한 경우)의 개수를 세어, 두 객체 간의 유사도를 나타내는 0부터 100 사이(양 끝값 포함)의 숫자를 반환해야 합니다. 즉, 일치하는 키/값 쌍이 하나도 없으면 0을, 모든 속성이 일치하면 100을 반환합니다.
유사도 계산 원리
유사도 백분율을 구하는 방법은 매우 간단합니다. 일치하는 속성의 개수를 더 작은 객체(키/값 쌍이 적은 객체)의 전체 속성 개수로 나눈 뒤, 여기에 100을 곱하면 됩니다. 작은 객체를 기준으로 삼는 이유는, 큰 객체 기준으로 계산하면 유사도가 과소평가될 수 있기 때문입니다.
구현 코드
개념을 이해했으니 이제 실제 함수 코드를 작성해 보겠습니다.
const a = {
Make: "Apple",
Model: "iPad",
hasScreen: "yes",
Review: "Great product!",
};
const b = {
Make: "Apple",
Model: "iPad",
waterResistant: false
};
const findSimilarity = (first, second) => {
const firstLength = Object.keys(first).length;
const secondLength = Object.keys(second).length;
const smaller = firstLength < secondLength ? first : second;
const greater = smaller === first ? second : first;
const count = Object.keys(smaller).reduce((acc, val) => {
if(Object.keys(greater).includes(val)){
if(greater[val] === smaller[val]){
return ++acc;
};
};
return acc;
}, 0);
return (count / Math.min(firstLength, secondLength)) * 100;
};
console.log(findSimilarity(a, b));코드 동작 설명
이 함수의 핵심 로직은 다음과 같습니다.
1. 속성 개수 확인: Object.keys()로 각 객체의 키 배열을 얻어 길이를 비교하고, 더 작은 객체와 더 큰 객체를 구분합니다.
2. 공통 속성 카운트: reduce()를 사용해 작은 객체의 각 키가 큰 객체에 존재하는지 확인하고, 키뿐만 아니라 값까지 동일한 경우에만 카운트를 증가시킵니다.
3. 백분율 변환: 일치 개수를 작은 객체의 속성 개수로 나누고 100을 곱해 최종 유사도를 반환합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
66.66666666666666
더 작은 객체인 b는 총 3개의 속성(Make, Model, waterResistant)을 가지고 있으며, 그중 2개(Make, Model)가 객체 a와 일치합니다. 따라서 2 ÷ 3 × 100 ≈ 66.67%라는 유사도가 계산됩니다.
참고 사항
이 방식은 문자열, 숫자, 불리언 등 원시 타입 값의 비교에는 잘 작동하지만, 객체나 배열처럼 참조 타입인 값은 === 연산자로 메모리 주소를 비교하기 때문에 내용이 같아도 다른 것으로 판단될 수 있습니다. 중첩된 객체의 깊은 비교가 필요하다면 재귀적으로 값을 비교하거나 Lodash의 isEqual 같은 유틸리티 라이브러리를 활용하는 것이 좋습니다.