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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

1097閲覧

VC# JSONファイルの読み込みと最大値、最小値を取得する方法が知りたい。

kishidamisao

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2023/02/28 08:40

編集2023/03/01 01:43

VC#でJSONファイルを読み込み、その後、JSONファイルのデータ(数値)の
最小値と最小値を取得する方法を教えてください。

「Newtonsoft.Json」と使用すればよいのか、それとも 「System.Text.Json」
の方が良いのでしょうか。
「JSONファイル」をデシリアライズ方法は、わかったのですが、その後の処理
方法が調べてもわかりませんでした。

「JSONファイル」をデシリアライズした後、どのようにデータを取得して良いか
教えてください。

LINQを使用して取得すれば良いのでしょうか。
その場合は、どのように使用すれば良いのでしょうか。

「JSONファイル」は、構造かされていて、その一部を取得する方法が知りたいのですが
どなたかご存知、教えてください。

また、javascriptでは、最大値、最小値を取得する関数があるのですが、
VC#でも、そのような関数があるのでしょうか。

よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/02/28 08:54

何を何で作っているかを質問欄を編集して追記してください。(例: Windows 10 の Visual Studio 2022 で Windows Forms アプリをターゲットフレームワーク .NET Framework 4.8 で作っています・・・とか) やりたいことを実現するために自分ではどこまで実装できていて、どこで躓いていて、何が分かれば解決できるかを、自分が書いたコードを質問欄に貼るなどして説明してください。丸投げは歓迎されません。 読んでください。 https://teratail.com/help/avoid-asking https://teratail.com/help/question-tips
kishidamisao

2023/03/01 00:19

やってほしい事ではではありません。 ここまで調べてのですが、この後の処理方法がわからないので聞いているのです。 ここまでは、わかったのですが、この後の処理方法がわからないのです。 情報があればと、いろいろ記載しましたが、データとかない方が良いということでしょうか いろいろ書物を購入して調べたのですが、そこにも、読み込み方法のみ記載されたましたが その後の処理方法が記載されていませんでした。 参考になる書物や、サイトなどでも良いのでわかれば教えていただければと思います。 次回使用する時は、なるべく抽象的に、詳しいことは記載しないで質問します。 Windows 10 の Visual Studio 2022 で Windows Forms アプリをターゲットフレームワーク .NET Framework 4.8 で作っています 読んでください。 https://teratail.com/help/avoid-asking https://teratail.com/help/question-tips にも方法は記載されていませんでした。
退会済みユーザー

退会済みユーザー

2023/03/01 01:11

話が通じているでしょうか? 上に書いた、 > やりたいことを実現するために自分ではどこまで実装できていて、どこで躓いていて、何が分かれば解決できるかを、自分が書いたコードを質問欄に貼るなどして説明してください。丸投げは歓迎されません。 は理解できませんか?
kishidamisao

2023/03/01 01:33

ですから、「JSONファイル」をデシリアライズした後、どのようにデータを取得して良いか 教えてください。これだけです。 javascriptとだと、10行程度で、最大値と最小値が取得できるのですが、VC#だとどのようにして 取得できるか記載されている情報が見つからないのでです。 データが取得方法がわかれば、その後の処理ができるので、その部分のみ教えて欲しいのです。 「JSONファイル」の場合は、構造化されているので、構造化されているファイルの一部を取得する方法が知りたいので、このような記載になったのです。
退会済みユーザー

退会済みユーザー

2023/03/01 01:42 編集

質問の「JSONファイルは、以下のフォーマットです」以下に書かれたモノは JSON として有効ではありません。全角文字が混じっているのがまず問題外なのですが、たとえそこを直してもまだ JSON として不正です。 > ここまでは、わかったのですが、この後の処理方法がわからないのです なので、出だしから分かってないと言わざるを得ません。 > ですから、「JSONファイル」をデシリアライズした後、どのようにデータを取得して良いか デシリアライズできると言ってますか? じゃあ、それをやるためのコードを書いてください。
kishidamisao

2023/03/01 01:51

using Newtonsoft.Json; // C:¥Work¥test.json を UTF-8 で開く using (var sr = new StreamReader(@"C:\Work\test.json", System.Text.Encoding.UTF8)) { // 変数 jsonData にファイルの内容を代入 var jsonData = sr.ReadToEnd(); // デシリアライズして person にセット person = JsonConvert.DeserializeObject<Person>(jsonData); } この後のデータ取得方法がわからないのです。 person にはビュアルスタジオで、テキスト情報をみると正しく表示されるのですが この後のデータの取り出しかたがわかりません。
退会済みユーザー

退会済みユーザー

2023/03/01 02:19

少なくとも Person クラスの定義と、できればその中身を示すサンプルを書いてもらわないと答えようがありません。
退会済みユーザー

退会済みユーザー

2023/03/01 03:34

待ってても情報は出てこないようなので、前の質問ベースに回答を書いておきます。
TN8001

2023/03/01 08:58

過去の質問で受付中のままのものが散見されます。 解決しているのでしたら「解決済」にしてください。 質問の編集ができるのでしたら「WPF」に直してください。 [「Visual Studio 2019」にて、「FWP」のC#プロジエクトで「Basic認証」をする方法](https://teratail.com/questions/340844)
guest

回答3

0

ベストアンサー

質問者さんが質問欄に書いた JSON 文字列(消してしまいましたが)は、 全角文字が混じっている他 JSON として有効ではありませんが、それを修正して以下のようにして、

JSON

1[ 2 { 3 "header": { 4 "discipline": 10, 5 "disciplineName": "Oceanographic products" 6 }, 7 "data": [ 8 "NaN", 9 -0.010565, 10 -0.053534, 11 0.020685, 12 0.102716, 13 0.106622, 14 0.005060, 15 0.016778, 16 0.130060, 17 0.173028, 18 0.294122, 19 0.321466, 20 0.344903, 21 0.376153, 22 0.368341, 23 0.112690 24 ] 25 } 26]

以下の記事のように Visual Studio の機能を使って C# のクラス定義を生成すると、

JSON 文字列から C# のクラス定義生成
http://surferonwww.info/BlogEngine/post/2020/05/10/generate-class-definition-from-json-string.aspx

以下のようになります。

C#

1public class Rootobject 2{ 3 public Class1[] Property1 { get; set; } 4} 5 6public class Class1 7{ 8 public Header header { get; set; } 9 public object[] data { get; set; } 10} 11 12public class Header 13{ 14 public int discipline { get; set; } 15 public string disciplineName { get; set; } 16}

上の JSON の "data" は文字列と数値が混ざった配列なので object[] 型にデシリアライズするということのようです。

数値だけなら Linq の Max メソッド、Min メソッドで最大値、最小値を取得できますが、余計なものが混じっているとそれを除去してから Max メソッド、Min メソッドを適用するという話になると思います。

Newtonsoft.Json と System.Text.Json では object[] にデシリアライズされた結果が異なります。

Newtonsoft.Json

イメージ説明

System.Text.Json

イメージ説明

なので、デシリアライザによって余計なものを除去して数値だけのコレクションにするやり方が変わってきます。以下がそのサンプルです。

C#

1string filepath = @"json ファイルのパス"; 2string jsonString = ""; 3using (StreamReader sr = File.OpenText(filepath)) 4{ 5 jsonString = sr.ReadToEnd(); 6} 7 8// Newtonsoft.Json 9var result1 = JsonConvert.DeserializeObject<List<Class1>>(jsonString); 10var listDouble1 = new List<double>(); 11if (result1 != null) 12{ 13 // object[] の各要素は object{string} または object{double} になる 14 object[] data = result1[0].data; 15 foreach (var item in data) 16 { 17 if (item != null) 18 { 19 if (item is double) 20 { 21 listDouble1.Add((double)item); 22 } 23 } 24 } 25} 26Console.WriteLine($"Max: {listDouble1.Max()}, Min: {listDouble1.Min()}"); 27 28// System.Text.Json 29var result2 = System.Text.Json.JsonSerializer.Deserialize<List<Class1>>(jsonString); 30var listDouble2 = new List<double>(); 31if (result2 != null) 32{ 33 // Newtonsoft.json と違って object[] の各要素は object{System.Text.Json.JsonElement} 34 // になる。ValueKind プロパティで文字列/数値の識別ができる 35 object[] data = result2[0].data; 36 foreach (var item in data) 37 { 38 if (item != null) 39 { 40 var jsonElement = (System.Text.Json.JsonElement)item; 41 if (jsonElement.ValueKind == System.Text.Json.JsonValueKind.Number) 42 { 43 listDouble2.Add(jsonElement.GetDouble()); 44 } 45 } 46 } 47} 48Console.WriteLine($"Max: {listDouble2.Max()}, Min: {listDouble2.Min()}"); 49 50// 結果は: 51// Max: 0.376153, Min: -0.053534 52// Max: 0.376153, Min: -0.053534

投稿2023/03/01 03:46

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kishidamisao

2023/03/01 04:25

ありがとうございました。 この方法で作業を行います。 誠にありがとうございました。
TN8001

2023/03/01 08:57

> デシリアライザによって余計なものを除去して数値だけのコレクションにするやり方が変わってきます。 "NaN"が余計かは状況次第というか、ふつうはdouble.NaNを期待しているような。 Newtonsoft.Jsonは、 public double[] data { get; set; } とするだけでdouble.NaNにしてくれます。 System.Text.Jsonは、NumberHandlingオプション(AllowNamedFloatingPointLiteralsかAllowReadingFromString)も必要です。 [JsonSerializerOptions.NumberHandling プロパティ (System.Text.Json) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.text.json.jsonserializeroptions.numberhandling) MinがNaNになっちゃうけど^^;
退会済みユーザー

退会済みユーザー

2023/03/01 09:11 編集

> "NaN"が余計かは状況次第というか、ふつうはdouble.NaNを期待しているような。 質問は最大値と最小値を得たいということなので、文字列の "NaN" も Double.NaN も余計ですね。 > Newtonsoft.Jsonは、 public double[] data { get; set; } とするだけでdouble.NaNにしてくれます。 上の回答の画像を見てください。object {string} となってますが? 文字列の ”NaN" は double.NaN と同じと言ってますか?
kishidamisao

2023/03/01 10:02

確認してみます。 ありがとうございます。
TN8001

2023/03/01 11:16

>> Newtonsoft.Jsonは、 public double[] data { get; set; } とするだけでdouble.NaNにしてくれます。 > 上の回答の画像を見てください。object {string} となってますが? 文字列の ”NaN" は double.NaN と同じと言ってますか? 「(dataの定義をdouble[]に変えれば)文字列の"NaN"がdouble.NaNとして扱われます」ということです(私の回答を見てください) (double配列が欲しい場合は)「"NaN"があってもいけますよ」という補足情報です。
退会済みユーザー

退会済みユーザー

2023/03/01 11:28 編集

失礼、Visual Studio が生成する object[] を double[] に変えるというのは見落としてました。と言うか、全く考えもしてなかったです。
guest

0

次回使用する時は、なるべく抽象的に、詳しいことは記載しないで質問します。

どうしてそういう考えに至るかがまったく理解できません。
当初の内容で「丸投げの質問」とされたのであれば、より具体的に書くべきです。
ふんわりした質問にはふんわりした回答しかできませんし、それでは問題は解決しないでしょう?

特にこのあたりの記載が不足しています。
3-5. あなたが何をしたかを書きましょう|質問するときのヒント

この後のデータ取得方法がわからないのです。
person にはビュアルスタジオで、テキスト情報をみると正しく表示されるのですが

なんで唐突にPersonが出てくるのでしょうか??当該JSONを使わないと意味がないでしょう?
コレってggって出てきたコードの丸写しですよね...
[Tips] Newtonsoft.Jsonライブラリの使用方法 | HIROs.NET Blog

kishidamisaoさんは「デシリアライズ方法は、わかった」とおっしゃっていますが、せいぜい「DeserializeObjectメソッドを使えばいいことが分かった」ぐらいにしか見えません(わからないことを責めているわけではありません)

最大値・最小値についてもggればすぐ情報は出てきます。
c# 最大値 最小値 - Google 検索

「ふんわりと使い方はわかってるつもりだが、実際にどう使えばいいのかわからない」といったところだとは思うのですが、だったらなおさら(エラーになっていてもいいので現状の)コードを出してください。

そうでないと結局1から説明することになってしまい、「コードをください・デバッグしてください等の丸投げの質問」と言われても仕方のないことです。


「Newtonsoft.Json」と使用すればよいのか、それとも 「System.Text.Json」
の方が良いのでしょうか。

.NET Core3.0以降であれば、標準で入っている「System.Text.Json」が第一候補です。
それ以前ならどちらもNuGetが必要ですので、まあ好みかなと思います(「Newtonsoft.Json」は気が利く・「System.Text.Json」はパフォーマンスがいい)
C# を使用した JSON のシリアル化と逆シリアル化 - .NET | Microsoft Learn

「JSONファイル」をデシリアライズした後、どのようにデータを取得して良いか

(通常の方法で)「デシリアライズ」できたのであれば、プロパティ(やフィールド)にアクセスするだけです。
ここで詰まっているということは、(当該jsonで)「デシリアライズ」できていないのでしょう。

まずは当該JSONと対応するクラスを作ります。
Visual Studio自体にその機能があります。
JSON または XML をクラスとして貼り付ける - Visual Studio (Windows) | Microsoft Learn

より気が利くWebサービスもあります。
c# json to class - Google 検索

大前提としてJSONが正しいフォーマットになっている必要があります。
提示JSONは正しくないので、仮にこうだったとします。

json

1[ 2 { 3 "header": { 4 "discipline": 10, 5 "disciplineName": "Oceanographic products" 6 }, 7 "data": [ 8 "NaN", 9 -0.010565, 10 -0.053534, 11 0.020685, 12 0.102716, 13 0.106622, 14 0.00506, 15 0.016778, 16 0.13006, 17 0.173028, 18 0.294122, 19 0.321466, 20 0.344903, 21 0.376153, 22 0.368341, 23 0.11269 24 ] 25 } 26]

このようなクラスが生成されました。

cs

1public class Rootobject 2{ 3 public Class1[] Property1 { get; set; } 4} 5 6public class Class1 7{ 8 public Header header { get; set; } 9 public object[] data { get; set; } 10} 11 12public class Header 13{ 14 public int discipline { get; set; } 15 public string disciplineName { get; set; } 16}

このままで使えなくもないですが、ちょっとこちらの希望と違うので編集します。

cs

1public class Class1 2{ 3 public Header Header { get; set; } 4 public double[] Data { get; set; } 5} 6 7public class Header 8{ 9 public int Discipline { get; set; } 10 public string DisciplineName { get; set; } 11}

あとはggって出てくるような使い方をすればいいわけですが、
「Newtonsoft.Json」は、気が利くので割とそのままでいけちゃいます。
「System.Text.Json」は、かなり厳格なのでオプション指定がいくつか必要になります。

C# を使用して JSON をシリアル化および逆シリアル化する方法 - .NET | Microsoft Learn

Newtonsoft.Json から System.Text.Json に移行する - .NET | Microsoft Learn

javascriptでは、最大値、最小値を取得する関数があるのですが、
VC#でも、そのような関数があるのでしょうか。

もちろんあります。
Enumerable.Max メソッド (System.Linq) | Microsoft Learn
Enumerable.Min メソッド (System.Linq) | Microsoft Learn

cs

1using System; 2using System.IO; 3using System.Linq; 4 5 6namespace Qi5lbhecgvfap7a 7{ 8 public class Class1 9 { 10 public Header Header { get; set; } 11 public double[] Data { get; set; } 12 } 13 14 public class Header 15 { 16 public int Discipline { get; set; } 17 public string DisciplineName { get; set; } 18 } 19 20 21 class Program 22 { 23 static void Main() 24 { 25 Dummy("test.json"); 26 var json = File.ReadAllText("test.json"); 27 28 // Newtonsoft.Json 29 var array = Newtonsoft.Json.JsonConvert.DeserializeObject<Class1[]>(json); 30 31 Console.WriteLine(array[0].Data.Max()); 32 Console.WriteLine(array[0].Data.Min()); 33 Console.WriteLine(array[0].Data.Where(x => !double.IsNaN(x)).Min()); 34 Console.WriteLine(); 35 36 37 // System.Text.Json 38 var options = new System.Text.Json.JsonSerializerOptions 39 { 40 // [System.Text.Json で大文字と小文字を区別しないプロパティ名の照合を有効にする方法 | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/standard/serialization/system-text-json/character-casing) 41 PropertyNameCaseInsensitive = true, 42 43 // [JsonNumberHandling 列挙型 (System.Text.Json.Serialization) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.text.json.serialization.jsonnumberhandling?view=net-7.0) 44 NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals, 45 }; 46 array = System.Text.Json.JsonSerializer.Deserialize<Class1[]>(json, options); 47 48 Console.WriteLine(array[0].Data.Max()); 49 Console.WriteLine(array[0].Data.Min()); 50 Console.WriteLine(array[0].Data.Where(x => !double.IsNaN(x)).Min()); 51 52 Console.ReadKey(); 53 } 54 55 static void Dummy(string path) 56 { 57 var json = @" 58[ 59 { 60 ""header"": { 61 ""discipline"": 10, 62 ""disciplineName"": ""Oceanographic products"" 63 }, 64 ""data"": [ 65 ""NaN"", 66 -0.010565, 67 -0.053534, 68 0.020685, 69 0.102716, 70 0.106622, 71 0.00506, 72 0.016778, 73 0.13006, 74 0.173028, 75 0.294122, 76 0.321466, 77 0.344903, 78 0.376153, 79 0.368341, 80 0.11269 81 ] 82 } 83] 84".Trim(); 85 86 File.WriteAllText(path, json); 87 } 88 } 89}
0.376153 NaN -0.053534 0.376153 NaN -0.053534

投稿2023/03/01 09:01

編集2023/08/15 15:37
TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2023/03/01 09:02

「解決済」の質問に(そういうつもりはまったくないがそう受けとられるであろう)説教臭い回答をしてもしょうがないのだが(文章書くのはだるいし)、あまりにもズレていると感じたので回答しました^^;
guest

0

間違って自己解決ししてしまいました。

投稿2023/03/01 04:21

編集2023/03/01 04:24
kishidamisao

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問