JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで2つのオブジェクトを比較し、類似度(0〜100%)を返す方法

JavaScriptでは、2つのオブジェクトがどれくらい似ているかを数値で評価したいケースがあります。本記事では、オブジェクト同士を比較して、類似度を0〜100の数値(パーセンテージ)として返す関数を実装する方法を解説します。

前提となるサンプルデータ

例として、次のような2つのオブジェクトを用意します。

const a = {
    Make: "Apple",
    Model: "iPad",
    hasScreen: "yes",
    Review: "Great product!",
};
const b = {
    Make: "Apple",
    Model: "iPad",
    waterResistant: false
};

やりたいこと

ここで作成したいのは、以下のような処理を行う関数です。

  • 2つのオブジェクトに共通するプロパティ(キーと値が両方一致しているもの)の数をカウントする
  • 類似度を0〜100までの数値(両端を含む)として返す
  • 1つも一致しなければ「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));

実行結果

コンソールへの出力は次のようになります。

66.66666666666666

結果の解説

この例では、小さい方のオブジェクト b は3つのプロパティを持っており、うち2つ(MakeModel)がオブジェクト a と一致しています。

したがって、類似度は「2 ÷ 3 × 100」=約66%となるわけです。

補足:整数に丸めたい場合

小数点以下が不要な場合は、Math.round() を使って丸めるのもおすすめです。

return Math.round((count / Math.min(firstLength, secondLength)) * 100);
// 出力例: 67

このように、Object.keys()reduce() を組み合わせることで、オブジェクト間の類似度を簡単に数値化できます。データ比較や差分チェックなどのさまざまな場面で応用できるテクニックなので、ぜひ覚えておきましょう。

  1. JavaScriptで2つのIPアドレス間に存在するアドレス数を求める方法

    問題2つのIPv4アドレスを引数として受け取り、その間に存在するIPアドレスの総数を返すJavaScript関数を作成します。ここでいう「間」とは、最初のアドレスを含み、最後のアドレスは含まない範囲を指します。IPv4アドレスは「0〜255の数値(オクテット)」を4つドットでつないだ構造になっており、各オクテットは256進法の1桁とみなすことができます。そのため、IPアドレス全体を1つの10進数に変換し、両者の差の絶対値を求めれば、間に存在するアドレス数を簡単に計算できます。考え方:オクテットごとの重み各オクテットには、左から順に次の重みが対応します。第1オクテット:2563(16,777,2

  2. JavaScriptで整数を素数のべき乗の積として表現する方法

    本記事では、正の整数を受け取り、その数を素数のべき乗の積として表す文字列を返すJavaScript関数の作成方法を解説します。 問題の概要 任意の正の整数 n を引数として受け取り、次の形式の文字列を返す関数を実装します。 n = "(p1**n1)(p2**n2)...(pk**nk)" ここで p1〜pk は素因数となる素数、n1〜nk はそれぞれに対応する指数です。「a**b」は「a の b 乗」を意味します。 例 例として 86240 を渡した場合、この数は次のように素因数分解できます。 86240 = 25 × 5 × 72 × 11 したがって、期待される出