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

JavaScriptで値を指定してオブジェクトのキーを検索する方法

JavaScriptでは、「オブジェクトの中に特定の値が存在するか」「その値はどのキーに紐づいているのか」を調べたい場面に出会うことがあります。本記事では、値を渡すとその値を持つすべてのキーを配列で返すカスタムメソッド keysOf() を、Object.prototype に追加する形で実装する方法を解説します。

サンプルデータとなるオブジェクト

まず、次のようなオブジェクトを例に考えてみましょう。

const obj = {
    "name": "Vivek Sharma",
    "occupation": "Software Engineer",
    "age": 23,
    "contacts": [{
        "name": "Mukul Sharma",
        "occupation": "Software Engineer",
        "age": 31,
    }, {
        "name": "Jay Sharma",
        "occupation": "Software Engineer",
        "age": 27,
    }, {
        "name": "Rajan Sharma",
        "occupation": "Software Engineer",
        "age": 32,
    }]
};

この例ではネストは1階層だけですが、実際のアプリケーションではもっと深い階層構造になることも珍しくありません。そこで、任意の深さのネストに対応できる汎用的な実装を目指します。

実現したいこと

今回作成するのは、Object.prototype.keysOf() という関数です。要件を整理すると以下のようになります。

  • 引数に検索したい値を受け取る
  • オブジェクト全体(ネストされたプロパティを含む)を走査する
  • その値と一致するキー名をすべて集め、配列として返す

実装コード

それでは、実際のコードを見てみましょう。

const keysOf = function(val, obj = this, res = []){
    const keys = Object.keys(obj);
    for(let ind = 0; ind < keys.length; ind++){
        if(obj[keys[ind]] === val){
            res.push(keys[ind]);
        }else if(typeof obj[keys[ind]] === 'object' &&
        !Array.isArray(obj[keys[ind]])){
            keysOf(val, obj[keys[ind]], res);
        }
    }
    return res;
};
Object.prototype.keysOf = keysOf;

// 使い方:値 23 を持つキーを検索
console.log(obj.keysOf(23));

コードの解説

  • デフォルト引数による設計: 第2引数 obj の初期値は this(メソッド呼び出し元のオブジェクト)、第3引数 res は結果を格納する配列です。再帰呼び出し時に同じ res を受け渡すことで、見つかったキーを一つの配列に蓄積できます。
  • 厳密な比較: 値の照合には厳密等価演算子 === を使用しているため、文字列と数値のように型が異なる値はマッチしません。
  • 再帰的な探索: プロパティの値が「オブジェクト型かつ配列以外」である場合にのみ再帰呼び出しを行います。これにより、入れ子になったオブジェクトの内部まで掘り下げて検索できます。

なお、この実装では配列そのものは探索対象外となっている点に注意してください。つまり、上記の contacts 配列内の各オブジェクトは検索されません。配列の中身まで対象にしたい場合は、条件分岐を拡張して配列要素に対しても再帰処理を実行するように変更する必要があります。

実行結果

このコードを実行すると、コンソールには次のように出力されます。

['age']

23 を持つプロパティはトップレベルの "age" キーだけであるため、結果はこの一要素だけの配列になります。

  1. JavaScriptで値に基づいてオブジェクトをグループ化する方法

    JavaScriptでは、reduce()メソッドを活用することで、配列内のオブジェクトを特定の値(プロパティ)に基づいて効率的にグループ化できます。たとえば、複数人のデータを「年齢」ごとにまとめたい場合などに役立ちます。ここでは、実際に動作するサンプルコードをもとに、実装手順と仕組みをわかりやすく解説します。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewpo

  2. JavaScriptで2つのオブジェクトを比較しながら配列のネストされた値をグループ化する方法

    この記事では、2つのオブジェクト(before と after)を比較しながら、ネストされた配列の値を1つの行にグループ化する方法を解説します。データの差分を表形式で整理したい場合などに役立つテクニックです。入力データの例まず、次のようなJSONオブジェクトがあるとします。before(変更前)と after(変更後)の2つの状態が含まれ、それぞれの device 配列の中に、id、price、features(機能名と価格)というネストされた構造を持っています。const input = { before: { device: [ { id: 1234