0

json.net (Newtonsoft) ライブラリを使用して、API json 応答を解析しています。ID 値とランク値だけが必要です。json は次のようになります。

{"items":
    [
        {"fields":
            {"entry":
                [
                    {"key":"Customer","value":"ABC Electronics"},
                    {"key":"Status","value":"Untouched"},
                    {"key":"Amount","value":"$1000"},
                    {"key":"rank","value":"3.0"}
                ]
            },
            "id":"1001",
            "owner":"dave@sales123.com"
        },
        {"fields":
            {"entry":
                [
                    {"key":"Customer","value":"General Products"},
                    {"key":"Status","value":"Developing"},
                    {"key":"Amount","value":"$6000"},
                    {"key":"rank","value":"6.0"}
                ]
            },
            "id":"1002",
            "owner":"john@sales123.com"
        }
    ]
}

クラス内に、リクエストを作成し、json をループして ID とランクを取得し、それらの値を新しい RankScore オブジェクトとして List クラス メンバーに追加するメソッドがあります。私の質問は、単にループして各キーをチェックするよりも、エントリ配列でキー == 「ランク」の「値」を見つけるためのより良い方法があるかどうかです。私が見つけられなかったLINQの方法はありますか?

public void MakeRequest(apiURL) {
    var requestUrl = new Uri(apiUrl, "/ranks/0");
    HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
    request.Credentials = new NetworkCredential(this.Username, this.Password);

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var token = JObject.Parse(reader.ReadToEnd());
            var items = token["items"];
            foreach (var item in items)
            {
                var id = item.Value<string>("id");
                var entries = item["fields"]["entry"];
                string rank = null;

                // **** Is there a better way to do this? ****
                foreach (var entry in entries) 
                {
                    if (entry.Value<string>("key") == "rank")
                    {
                        rank = entry.Value<string>("value");
                        break;
                    }
                }
                var ranking = new RankScore(int.Parse(id), rank);
                this.Ranks.Add(ranking);
            }

        }
    }
}
4

2 に答える 2

1

簡単な答えはノーです。他の何かにループの一部を任せることもできますが、LINQ を使用することでパフォーマンスが向上するソリューションを考え出すことはできません (コレクションをループするだけでもあります)。

オブジェクトにシリアル化できるコードを単純にクリーンアップすることが目標である場合は、コードに単純なループが含まれます (もちろん、json.NET は多くのループを実行します)。

for (int i = 0; i < Obj.items.Length; i++)
{
    Obj.items[i].id //do something with this here
}

私は個人的にそれをお勧めしませんが。シンプルな方法が好きです。もう 1 つの (ばかげた) アイデアは、RegEx を使用することです。行数は少なくなりますが、パフォーマンスは大幅に低下します。基本的に、繰り返しを削除するつもりはありません。抽象化を使用してその一部を実行できますが、実際には意味がありません。あなたがjsonでもっと多くのことをするつもりでない限り、私はあなたが持っているものに固執します。他の場所で json を使用する場合は、オブジェクトにシリアル化します。

于 2012-12-11T22:34:43.747 に答える
1

JSON の結果ごとに複数の値を検索することを計画している場合は、データを取得して、探しているものをより効率的に検索できるようにするデータ構造に入れることは価値がある可能性があります。例として、キーを値にマップする を作成することもできますがDictionary、データ構造を 1 回だけ検索する場合は、それを作成するDictionaryほうが作業量が増えるため、コードはそのままにしておく必要があります。そのままです。

必要なことを実行するために必要なコードの量を削減できる可能性があります (いくつかの簡略化が一見して目立ちます) が、すべてを検索する基本的なアルゴリズムは変更されません。

于 2012-12-11T22:26:41.250 に答える