質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

unity(C#)でjson取得したデーター[ { { 個々 } } ] のデーターを取得したい

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,193

score 10

以下のコードが前提となるデーターです。

{
   "forecasts": [
        {
            "dateLabel": "明日",
            "telop": "曇のち雨",
            "date": "2019-02-22",
            "temperature": {
                "min": {
                    "celsius": "5",
                    "fahrenheit": "41.0"
                },
                "max": {
                    "celsius": "14",
                    "fahrenheit": "57.2"
                }
            },
            "image": {
                "width": 50,
                "url": "http://weather.livedoor.com/img/icon/13.gif",
                "title": "曇のち雨",
                "height": 31
            }
        },
    ],
}


この中のtemperatureの中のminの中のfahrenheitが取得したいのですがどうしても取得できませんでした。やり方を知っていたら教えて下さい、よろしくお願いします。

追記
自分が書いていたコードです

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using MiniJSON;
using JsonData;

public class WeatherAPI_test1 : MonoBehaviour
{

    static public string url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=400040";//天気URL

    string advis;
    string image;

    void Start()
    {

        StartCoroutine("connectdata");
    }

    private IEnumerator connectdata()
    {
        WWW www = new WWW(url);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {

            print("Error downloading: " + www.error);

        }
        else
        {

            string jsonText = www.text;//受け取ったデーターをjsonTextにIN

            JsonDataClass jsonDataClass;
            JsonDataClas_image jsonDataClas_image;

            jsonDataClass = JsonUtility.FromJson<JsonDataClass>(jsonText);


            Debug.Log(jsonText);

            var json = jsonText;
            //(1階層目)
            var jsonData = MiniJSON.Json.Deserialize(json) as Dictionary<string, object>;//全体の並列取得
            //(2階層目)
            var description = jsonData["description"] as Dictionary<string, object>;//天気概況文の配列
            var forecasts = (IList)jsonData["forecasts"];//府県天気予報の予報日毎の配列 
            var pinpointLocations = (IList)jsonData["pinpointLocations"];//ピンポイント予報の発表地点の配列
            var location = jsonData["location"] as Dictionary<string, object>;//予報を発表した地域を定義 





            //(3階層目)
            var forecasts_0 = (IDictionary)forecasts[0];
            var forecasts_1 = (IDictionary)forecasts[1];
            var forecasts_2 = (IDictionary)forecasts[2];



            var pinpointLocations_0 = (IDictionary)pinpointLocations[0];
            var pinpointLocations_1 = (IDictionary)pinpointLocations[1];
            var pinpointLocations_2 = (IDictionary)pinpointLocations[2];
            var pinpointLocations_3 = (IDictionary)pinpointLocations[3];
            var pinpointLocations_4 = (IDictionary)pinpointLocations[4];
            var pinpointLocations_5 = (IDictionary)pinpointLocations[5];
            var pinpointLocations_6 = (IDictionary)pinpointLocations[6];
            var pinpointLocations_7 = (IDictionary)pinpointLocations[7];



            Debug.Log(jsonDataClass.title);
            OUTPutUI_script.title = jsonDataClass.title;

            advis = (string)description["text"];

            OUTPutUI_script.advice = advis.Replace("\n", "");

            OUTPutUI_script.today_dateLabel = (string)forecasts_0["dateLabel"];
            OUTPutUI_script.today_weather = (string)forecasts_0["telop"];
            OUTPutUI_script.today_date = (string)forecasts_0["date"];

            OUTPutUI_script.tomorrow_dateLabel = (string)forecasts_1["dateLabel"];
            OUTPutUI_script.tomorrow_weather = (string)forecasts_1["telop"];
            OUTPutUI_script.tomorrow_date = (string)forecasts_1["date"];

            OUTPutUI_script.afterTomorrow_dateLabel = (string)forecasts_2["dateLabel"];
            OUTPutUI_script.afterTomorrow_weather = (string)forecasts_2["telop"];
            OUTPutUI_script.afterTomorrow_date = (string)forecasts_2["date"];

            Debug.Log((string)forecasts_0["dateLabel"]);//予報日(今日、明日、明後日のいずれか)
            Debug.Log((string)forecasts_0["telop"]);//天気
            Debug.Log((string)forecasts_0["date"]);//予報日

            Debug.Log((string)forecasts_1["dateLabel"]);//予報日(今日、明日、明後日のいずれか)
            Debug.Log((string)forecasts_1["telop"]);//天気
            Debug.Log((string)forecasts_1["date"]);//予報日 



            //            Debug.Log((string)forecasts_2["dateLabel"]);//予報日(今日、明日、明後日のいずれか)
            //            Debug.Log((string)forecasts_2["telop"]);//天気
            //            Debug.Log((string)forecasts_2["date"]);//予報日 

            Debug.Log((string)pinpointLocations_0["link"]);//リンク
            Debug.Log((string)pinpointLocations_0["name"]);//リンク
            Debug.Log((string)pinpointLocations_1["link"]);//リンク
            Debug.Log((string)pinpointLocations_1["name"]);//リンク

            Debug.Log((string)description["text"]);//天気概況本文
            Debug.Log((string)description["publicTime"]);//天気概況文の発表時刻



            //            Debug.Log((double)location["city"]);//都市
            Debug.Log((string)location["area"]);//地方名(例・九州地方)
            Debug.Log((string)location["prefecture"]);//都道府県名(例・福岡県)
            Debug.Log((string)location["city"]);//1次細分区名(例・八幡)



            //            Debug.Log((double)main["temp_max"]);//最高気温
            //            Debug.Log((double)coord["lon"]);//経度
            //            Debug.Log((double)main["pressure"]);//気圧
            //            Debug.Log((long)main["humidity"]);//湿度
            //            Debug.Log((double)wind["speed"]);//風速
            //            Debug.Log((string)jsonData["name"]);//都市名
            //            Debug.Log((string)sys["country"]);//国名
            //            Debug.Log((long)sys["sunrise"]);//日の出時間
            //            Debug.Log((long)sys["sunset"]);//日没時間  


        }
    }
}
namespace JsonData
{
    public class JsonDataClass
    {

        public string publicTime;//予報の発表日時

        public string title;//タイトル・見出し

        public string link;

        public string telop;

    }
    public class JsonDataClas_image
    {
        public string image;
    }
}


でデーターを取得して

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class OUTPutUI_script : MonoBehaviour
{

    static public string title;

    static public string advice;

    static public string img;

    static public string today_weather;
    static public string today_date;
    static public string today_dateLabel;

    static public string tomorrow_weather;
    static public string tomorrow_date;
    static public string tomorrow_dateLabel;

    static public string afterTomorrow_weather;
    static public string afterTomorrow_date;
    static public string afterTomorrow_dateLabel;

    public Text Title;

    public Text Advice;

    public Text Today_weather;
    public Text Today_date;
    public Text Today_dateLabel;

    public Text Tomorrow_weather;
    public Text Tomorrow_dat;
    public Text Tomorrow_dateLabel;

    public Text AfterTomorrow_weather;
    public Text AfterTomorrow_dat;
    public Text AfterTomorrow_dateLabe;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

        if (System_script.switch_jg == "1")
        {
            SwitchON();
        }

    }
    public void SwitchON()
    {
        Title.text = title;

        Advice.text = advice;

        Today_date.text = today_date;
        Today_weather.text = today_weather;
        Today_dateLabel.text = today_dateLabel;

        Tomorrow_dat.text = tomorrow_date;
        Tomorrow_weather.text = tomorrow_weather;
        Tomorrow_dateLabel.text = tomorrow_dateLabel;

        AfterTomorrow_dat.text = afterTomorrow_date;
        AfterTomorrow_weather.text = afterTomorrow_weather;
        AfterTomorrow_dateLabe.text = afterTomorrow_dateLabel;
    }
}


で出力しています
上のjsonデーターは取得したデーターの中の自分が取り出せなくて困っている部分だけを書き出した物です。

追記遅くなってしまってごめんなさい。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • BluOxy

    2019/02/21 12:44

    >どうしても取得できませんでした。
    試したこと(例えば、JSONで取得しようとして動かなかったコードや使用したライブラリ)を載せてください。

    キャンセル

  • 退会済みユーザー

    2019/03/29 15:01

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

+1

C#でJsonを取り扱うのであれば、Json.NET等のライブラリを使うことが基本的に多いと思います。
環境を準備するために以下の手順が必要になります。

  1. http://www.newtonsoft.com/jsonへ行って、zipをダウンロード
  2. zipファイルを解凍して「Bin\Net20\Newtonsoft.json.dll」をUnityのPluginsフォルダにコピー

準備が出来次第、次の手順を行います。

  1. Jsonに対応するオブジェクトの定義
  2. Json-オブジェクト間の変換(シリアライズ・デシリアライズ)を行い取得したデータにアクセスする

詳細については以下に記載しますので、ご参考にしてください。

Json.NETで提示されたJsonコードを取り扱う場合は、Jsonの構造に合わせてクラスの定義を行います。
(json2csharpというサイトでクラス定義に変換しました)

public class Min
{
    public string celsius { get; set; }
    public string fahrenheit { get; set; }
}

public class Max
{
    public string celsius { get; set; }
    public string fahrenheit { get; set; }
}

public class Temperature
{
    public Min min { get; set; }
    public Max max { get; set; }
}

public class Image
{
    public int width { get; set; }
    public string url { get; set; }
    public string title { get; set; }
    public int height { get; set; }
}

public class Forecast
{
    public string dateLabel { get; set; }
    public string telop { get; set; }
    public string date { get; set; }
    public Temperature temperature { get; set; }
    public Image image { get; set; }
}

public class RootObject
{
    public List<Forecast> forecasts { get; set; }
}

あとはJsonをForecastまたはRootObjectクラスのインスタンスとして取り込み、メンバーにアクセスすれば良いです。インスタンスとして取り込むことをデシリアライズって言います。

コード例は次になります。

public void Hoge(){
    using (var sr = new StreamReader(jsonファイルのパス, Encoding.UTF8))
    {
        var data =  sr.ReadToEnd();
        var obj  = JsonConvert.DeserializeObject<RootObject>(data);

        //temperatureの中のminの中のfahrenheitを取得
        Console.WriteLine(obj.forecasts.First().temperature.min.fahrenheit); 
    }
}

参考:UnityでJson.NETを使う
他のライブラリ:[C#] C#でJSONを扱う方法まとめ

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

最初に

追記を見ました。
趣旨が変わるので別途こちらで回答します。

次にご質問する際はお互いの問答が円滑に行えるよう、ご自身でされたことを事前に書くようにしてください。
先の回答のようにnitiyoubiさんの求めている内容からはどうしても離れてしまいますから。

回答+気になる点

全体的な実装で気になった点が変数名に数字をつけるのではなく、foreachでコレクションの全てを列挙するべきです。

もしforecastsの要素数が増えて、例えば5つ目の部分が欲しいとなった場合、その都度forecasts_4などと変数を追加しなければいけなくなります。

同じコードを書いているな、と思ったら書かないよう色々考えてみるとコードが物凄く減り、見やすく管理しやすいコードになります。DRYの法則で調べてみると良いでしょう。

その点を踏まえてminfahreheitにアクセスする方法を、nitiyoubiさんが添付されたコードを改造して作りました。既存の動きとほぼ似たような振る舞いをするはずです。

なお、実際に動作確認はしていないため何も考えずに流用はせず、参考程度に見てください。
(つまり、流用された際に発生した細かいコンパイルエラーはお手数ですが自分で直してください、自分はコード代行屋ではないので)

WeatherAPI_test1 の実装

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using MiniJSON;
using JsonData;

public class WeatherAPI_test1 : MonoBehaviour
{

    static public string url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=400040";//天気URL

    string advis;
    string image;

    void Start()
    {

        StartCoroutine("connectdata");
    }


    private IEnumerator connectdata()
    {
        WWW www = new WWW(url);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {

            print("Error downloading: " + www.error);

        }
        else
        {

            string jsonText = www.text;//受け取ったデーターをjsonTextにIN
            Debug.Log(jsonText);

            var json = jsonText;
            //(1階層目)
            var jsonData = MiniJSON.Json.Deserialize(json) as Dictionary<string, object>;//全体の並列取得
            //(2階層目)
            var description = jsonData["description"] as Dictionary<string, object>;//天気概況文の配列
            var forecasts = (IList)jsonData["forecasts"];//府県天気予報の予報日毎の配列 
            var pinpointLocations = (IList)jsonData["pinpointLocations"];//ピンポイント予報の発表地点の配列
            var location = jsonData["location"] as Dictionary<string, object>;//予報を発表した地域を定義 

            foreach(var forecast in forecasts.Cast<IDictionary>().Select((item, index)=> new { item, index}){
                OUTPutUI_script.dateLabel[(DateTimeTypes)forecast.index] = (string)forecast.item["dateLabel"];
                OUTPutUI_script.weather[(DateTimeTypes)forecast.index] = (string)forecast.item["telop"];
                OUTPutUI_script.date[(DateTimeTypes)forecast.index] = (string)forecast.item["date"];

                var temprature = (IDictionary)forecast["temperature"];
                var min = (IDictionary)temprature["min"];

                //nitiyoubiさんの求めているもの
                Console.Log(min["fahreheit"]);

                Debug.Log((string)forecast.item["dateLabel"]);//予報日(今日、明日、明後日のいずれか)
                Debug.Log((string)forecast.item["telop"]);//天気
                Debug.Log((string)forecast.item["date"]);//予報日
            }

            foreach(var pinpointLocation in pinpointLocations.Cast<IDictionary>()){
                /* 
                このループの中で以下の処理と同等のことができるので、
                変数名を「変数+数字」の形式にしなくて良い。
                var pinpointLocations_0 = (IDictionary)pinpointLocations[0];
                var pinpointLocations_1 = (IDictionary)pinpointLocations[1];
                var pinpointLocations_2 = (IDictionary)pinpointLocations[2];
                ・・・
                */
                Debug.Log((string)pinpointLocation["link"]);//リンク
                Debug.Log((string)pinpointLocation["name"]);//名前

            }

            Debug.Log(jsonDataClass.title);
            OUTPutUI_script.title = jsonDataClass.title;

            advis = (string)description["text"];

            OUTPutUI_script.advice = advis.Replace("\n", "");

            Debug.Log((string)description["text"]);//天気概況本文
            Debug.Log((string)description["publicTime"]);//天気概況文の発表時刻
            Debug.Log((string)location["area"]);//地方名(例・九州地方)
            Debug.Log((string)location["prefecture"]);//都道府県名(例・福岡県)
            Debug.Log((string)location["city"]);//1次細分区名(例・八幡)
        }
    }
}

OUTPutUI_scriptの実装

public class OUTPutUI_script : MonoBehaviour
{

    static public string title;
    static public string advice;
    static public string img;

    public static Dictionary<DateTimeTypes,string> weather;
    public static Dictionary<DateTimeTypes,string> date;
    public static Dictionary<DateTimeTypes,string> dateLabel;

    public Text Title;
    public Text Advice;

    public Text Today_weather;
    public Text Today_date;
    public Text Today_dateLabel;

    public Text Tomorrow_weather;
    public Text Tomorrow_dat;
    public Text Tomorrow_dateLabel;

    public Text AfterTomorrow_weather;
    public Text AfterTomorrow_dat;
    public Text AfterTomorrow_dateLabe;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

        if (System_script.switch_jg == "1")
        {
            SwitchON();
        }

    }
    public void SwitchON()
    {
        Title.text = title;

        Advice.text = advice;

        Today_date.text = date[DateTimeTypes.Today];
        Today_weather.text = weather[DateTimeTypes.Today];
        Today_dateLabel.text = dateLabel[DateTimeTypes.Today];

        Tomorrow_dat.text = date[DateTimeTypes.Tomorrow];
        Tomorrow_weather.text = weather[DateTimeTypes.Tomorrow];
        Tomorrow_dateLabel.text = dateLabel[DateTimeTypes.Tomorrow];

        AfterTomorrow_dat.text = date[DateTimeTypes.AfterTomorrow];
        AfterTomorrow_weather.text = weather[DateTimeTypes.AfterTomorrow];
        AfterTomorrow_dateLabe.text = dateLabel[DateTimeTypes.AfterTomorrow];
    }
}

public enum DateTimeTypes{,
    Today = 0,
    Tomorrow = 1,
    AfterTomorrow = 2,
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る