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

JavaScript로 두 객체의 유사도 비교하기 – 0~100 사이 백분율 값을 반환하는 함수 만들기

두 객체의 유사도를 백분율로 계산하는 방법

다음과 같은 두 개의 객체가 있다고 가정해 보겠습니다.

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 같은 유틸리티 라이브러리를 활용하는 것이 좋습니다.