JavaScriptで2つのオブジェクト間の値が異なる最初のプロパティを取得する方法
開発現場では、ほとんどのキーと値のペアが同一でありながら、一部のキーだけ値が異なる2つのオブジェクトを比較したい場面がよくあります。本記事では、2つのオブジェクトを引数として受け取り、値が異なる最初のキーを返す関数の実装方法を解説します。すべてのキーの値が完全に一致する場合は、-1を返す仕様とします。
サンプルデータ
まず、比較対象となる2つのオブジェクトを用意します。
const obj1 = {
name: 'Rahul Sharma',
id: '12342fe4554ggf',
isEmployed: true,
age: 45,
salary: 190000,
job: 'Full Stack Developer',
employedSince: 2005
}
const obj2 = {
name: 'Rahul Sharma',
id: '12342fe4554ggf',
isEmployed: true,
age: 45,
salary: 19000,
job: 'Full Stack Developer',
employedSince: 2005
}
この例では、salaryプロパティだけが値が異なっています(190000と19000)。そのため、関数は「salary」を返す必要があります。
実装の考え方
基本的なアプローチは以下のとおりです。
- 1つ目のオブジェクトのキーを先頭から順に走査し、2つ目のオブジェクトの同名キーの値と比較します。
- 値が一致しないキーが見つかった時点で、そのキーを結果として返します。
- 最後まで走査しても不一致が見つからなければ、-1を返します。
なお、forEach()はコールバック内でreturnしてもループ全体を中断できないため、複数の相違点がある場合に意図しないキーが返される可能性があります。「最初の」不一致キーを確実に取得するには、条件に合う最初の要素を返した時点で走査を終えるArray.prototype.find()を使うのが安全です。
コード例
const difference = (obj1, obj2) => {
const keyFound = Object.keys(obj1).find(
key => obj1[key] !== obj2[key]
);
return keyFound || -1;
};
console.log(difference(obj1, obj2));
Object.keys()で1つ目のオブジェクトのキー一覧を取得し、find()によって各キーの値を厳密等価演算子(!==)で比較しています。不一致キーが見つかれば即座に反復を終了してそのキーを返し、見つからなければundefinedが返るため、|| 演算子によって-1に変換されます。
実行結果
コンソールには次のように出力されます。
salary
補足:ネストされたオブジェクトを扱う場合の注意点
上記の比較では厳密等価演算子を使用しているため、文字列と数値といった型の違いも検出できます。ただし、プロパティの値にオブジェクトや配列が含まれる場合は参照の比較となるため、中身が同一でも別インスタンスなら「不一致」と判定される点に注意が必要です。ネストされたデータを深く比較したい場合は、JSON.stringify()で文字列化して比較するか、再帰処理による深い比較(deep comparison)を実装することをおすすめします。
-
Androidで2つの日付の差分(日数)を取得する方法【サンプルコード付き】
はじめに この記事では、Androidアプリで2つの日付の差分(日数)を取得する方法を、実際に動作するサンプルコードとともに解説します。日付の差分計算は、利用期間の表示やイベントまでの残り日数のカウントなど、さまざまな場面で役立つ基本的な処理です。 実装の手順 ステップ1:Android Studioで新規プロジェクトを作成 Android Studioを起動し、メニューから「File」→「New Project」を選択します。必要な項目をすべて入力して、新しいプロジェクトを作成しましょう。 ステップ2:レイアウトファイル(activity_main.xml)の編集 res/layout/ac
-
MySQLで2つのタイムスタンプの差を秒単位で計算する方法
MySQLでは、組み込み関数である TIMEDIFF() と TIME_TO_SEC() を組み合わせることで、2つのタイムスタンプの差を簡単に秒単位で求めることができます。基本構文2つのタイムスタンプ列の差を秒数として取得するには、以下の構文を使用します。SELECT TIME_TO_SEC(TIMEDIFF(カラム名1, カラム名2)) AS 別名 FROM テーブル名;各関数の役割TIMEDIFF(): 2つの日時・時刻の差を時間値(HH:MM:SS形式)として返しますTIME_TO_SEC(): 時間値を総秒数に変換しますサンプルテーブルの作成それでは、実際に動作を確認してみましょう。