1. ホーム
  2. javascript

[解決済み] JavaScriptでJSONを検索する

2022-03-03 22:34:20

質問

のデータを検索するために、ループ以外の良い方法はありますか? JSON ? 編集と削除のためです。

for(var k in objJsonResp) {
  if (objJsonResp[k].txtId == id) {
    if (action == 'delete') {
      objJsonResp.splice(k,1);
    } else {
      objJsonResp[k] = newVal;
    }
    break;
  }
}

データはマップのリストとして配置されます。 みたいな感じ。

[
  {id:value, pId:value, cId:value,...},
  {id:value, pId:value, cId:value,...},
  ...
]

解決方法は?

(JSON文字列はすでにオブジェクトグラフ(この場合は配列)にデシリアライズされています)。

いくつかのオプションがあります。

配列の代わりにオブジェクトを使用する

もし、あなたがこのものの生成をコントロールしているのなら、それは があります。 は配列でなければならないのでしょうか?もしそうでないなら、もっと簡単な方法があるからです。

これが元のデータだとします。

[
    {"id": "one",   "pId": "foo1", "cId": "bar1"},
    {"id": "two",   "pId": "foo2", "cId": "bar2"},
    {"id": "three", "pId": "foo3", "cId": "bar3"}
]

代わりに以下のようにしていただけませんか?

{
    "one":   {"pId": "foo1", "cId": "bar1"},
    "two":   {"pId": "foo2", "cId": "bar2"},
    "three": {"pId": "foo3", "cId": "bar3"}
}

そうすれば、IDで該当するエントリーを探すのは簡単です。

id = "one"; // Or whatever
var entry = objJsonResp[id];

...更新しているのと同じです。

objJsonResp[id] = /* New value */;

...そして、それを削除する。

delete objJsonResp[id];

これは、JavaScriptでは、プロパティ名を文字列として使用してオブジェクトにインデックスを付けることができるという事実を利用しています。 id 上記の

ID-Indexマップを入れる

(馬鹿な考えで、上記より前のものです。歴史的な理由で保管しています。)

この場合、配列の中を検索する以外に方法はありません。ただし、マップを置きたい場合は別で、オブジェクトの生成をコントロールできる場合は可能です。例えば、元々このようなオブジェクトがあったとします。

[
    {"id": "one",   "pId": "foo1", "cId": "bar1"},
    {"id": "two",   "pId": "foo2", "cId": "bar2"},
    {"id": "three", "pId": "foo3", "cId": "bar3"}
]

生成コードでid-indexマップを提供することができる。

{
    "index": {
        "one": 0, "two": 1, "three": 2
    },
    "data": [
        {"id": "one",   "pId": "foo1", "cId": "bar1"},
        {"id": "two",   "pId": "foo2", "cId": "bar2"},
        {"id": "three", "pId": "foo3", "cId": "bar3"}
    ]
}

そして、変数に id のエントリを取得します。 id は些細なことです。

var index = objJsonResp.index[id];
var obj = objJsonResp.data[index];

これは、プロパティ名を使ってオブジェクトにインデックスを付けられるという利点を利用したものです。

もちろん、そうすると配列を変更したときにマップを更新しなければならず、メンテナンスの問題が発生する可能性があります。

しかし、オブジェクトの生成を制御できない場合や、idとindexのマップを更新するのはコード量が多すぎる、あるいはメンテナンスの問題がある場合は、ブルートフォースサーチを行う必要があります。

ブルートフォースサーチ(修正版)

ややOT(ただし した という質問をしています :-) ) ですが、配列をループするコードが正しくありません。 詳細はこちら を使用することはできませんが for..in を使用して配列のインデックスをループさせることができます(というか、ループさせる場合は特別な苦労が必要です)。 for..in をループします。 オブジェクトのプロパティ ではなく 配列のインデックス . スパースでない配列の場合(この配列はスパースでない)、標準的な昔ながらのループが最適です。

var k;
for (k = 0; k < someArray.length; ++k) { /* ... */ }

または

var k;
for (k = someArray.length - 1; k >= 0; --k) { /* ... */ }

どちらか好きな方を選んでください(後者の方が必ずしもすべての実装で速いとは限らないので、私には直感に反するのですが、そこはそれとして)。(ただし スパース 配列の場合は for..in ただし、この場合も落とし穴を避けるために、特別な注意を払う必要があります。)

使用方法 for..in 配列に は単純なケースで動作します。なぜなら、配列はインデックスごとにプロパティを持ち、他の唯一のデフォルトプロパティ ( length とそのメソッド)はnon-enumerableとしてマークされています。しかし、配列オブジェクトに他のプロパティを設定する (もしくはフレームワークが設定する) とすぐに壊れてしまいます (これは完全に正しいです。配列は単なるオブジェクトで length プロパティがあります)。