2017-07-21 22 views
1

我有以下解析JSONW¯¯可變鍵值對在C#

[ 
    {  
    "name": "ATVI", 
    "dailyClosePrice": [ 
     { 
     "3/15/2017": 210.08, 
     "4/6/2017": 235.08, 
     "4/21/2017": 243.61, 
     "2/16/2017": 205.43 
     } 
    ] 
    }, 
    { 
    "name": "ADBE", 
    "dailyClosePrice": [ 
     { 
     "3/15/2017": 241.96, 
     "4/6/2017": 270.22, 
     "4/21/2017": 281.22, 
     "2/16/2017": 225.26 
     } 
    ] 
    } 
] 

實際的文件比2更多的人,但你可以看到有兩個 主要目的在這裏。 我在分析鍵值對(例如"3/15/2017": 210.08)時遇到問題。

我需要一類離開這裏,我想一個例子類將有

class Stock 
{ 
    public string Name{get;set;} 
    public List<Entry> Prices{get;set;} 
} 

class Entry 
{ 
    public string Date{get;set;} 
    public double Price{get;set;} 
} 

所以我想將文件解析成一個 列表

我想我可以使用一個StreamReader並使用Seek方法找到 一個「:」,但是我遇到的麻煩是如何才能夠只讀「ATVI」。例如,一旦我獲得「ATVI」,我將該字符串設置爲股票中的名稱,然後可以搜索「{」並閱讀「2017/3/15」,並將其設置爲條目中的日期,然後尋找「 :「並在雙讀等。

如果我這樣做,我不知道如何閱讀流的選擇元素,在C#中。在C#中,我主要閱讀的是具有相同間距的字符串,通常我會使用C來處理更復雜的事情,但是我真的希望使用C#而不是C來完成此操作。

我不在乎我需要使用什麼方法,我只是想在文件中讀取。

如果我有類似下面,我只想用NewtonSoft

[ 
    { 
    "name": "ATVI", 
    "dailyClosePrice": [ 
     {"Date":"3/15/2017", "price":210.08}, 
     {"Date":"3/15/2017", "price": 210.08}, 
     {"Date":"4/6/2017", "price": 235.08}, 
     {"Date":"4/21/2017", "price": 243.61} 
    ] 
    }, 
    { 
    "name": "ADBE", 
    "dailyClosePrice": [ 
     {"Date":"3/15/2017", "price":210.08}, 
     {"Date":"3/15/2017", "price": 210.08}, 
     {"Date":"4/6/2017", "price": 235.08}, 
     {"Date":"4/21/2017", "price": 243.61} 
    ] 
    } 
] 
+1

你爲什麼要這樣手動,而不是這樣做只是使用專門爲目的而設計的庫,並有可能做它遠遠比你更好(或I)可以嗎? – DavidG

+0

我使用NewtonSoft作爲我的其他JSON文件,但是這個有一個奇怪的格式 –

+0

奇怪的是什麼? – DavidG

回答

5

你絕對不應該由手工解析這個 - Json.NET將與這絕對精品,只要你模型,可以正確。 JSON表示一個對象列表,其中每個對象都有一個name(字符串)和一個dailyClosePrice,它似乎是一個總是有單個值的列表,而這個列表又是一個將對象映射到價格的日期。你可以代表相當容易:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Newtonsoft.Json; 

public class Stock 
{ 
    public string Name { get; set; } 
    public List<Dictionary<string, decimal>> DailyClosePrice { get; set; } 
} 

class Test 
{ 
    static void Main(string[] args) 
    { 
     string json = File.ReadAllText("test.json"); 
     var stocks = JsonConvert.DeserializeObject<List<Stock>>(json); 

     foreach (var stock in stocks) 
     { 
      Console.WriteLine($"Name: {stock.Name}"); 
      Console.WriteLine("Prices:"); 
      // Assume there's only ever a single entry, at least for now... 
      var prices = stock.DailyClosePrice.Single(); 
      // TODO: Parse the (ugly, US-based) date format... 
      var entries = prices.Select(kvp => new { Date = kvp.Key, Price = kvp.Value }); 
      foreach (var entry in entries) 
      { 
       Console.WriteLine($" {entry.Date}: {entry.Price}"); 
      } 
     } 
    } 
} 

現在Stock類是很醜陋,但它代表什麼的JSON - 那麼它應該是很容易的是表示轉換成一個更可口之一其餘的碼。

+0

非常感謝:)我想知道你是否會發生知道我可以在哪裏閱讀(kvp => new {Date = kvp.Key,Price = kvp.Value})我有時會使用類似這樣的表達式,但希望我更深入地瞭解 –

+0

@DevinAndresSalemi:基本上,找到一個很好的LINQ教程。 (或者我的書,C#深入,當然:) –

+0

@jonskeet你爲什麼這樣說:「醜陋的,美國的」我真的很好奇。不要擔心,我不是一個政治家,你也不會這樣對你,但你必須有一個合理的理由。 – CodingYoshi

1

您始終可以使用this technique爲您的JSON創建C#類。

您需要以下類的JSON:

public class Stock 
{ 
    public string Name { get; set; } 
    public IEnumerable<IDictionary<DateTime, float>> DailyClosePrice { get; set; } 
} 

下載JSON.NET庫(它可以作爲NuGet包)。然後,使用這樣的庫,和你做:

var stocks = JsonConvert.DeserializeObject<List<Stock>>("YourJSON"); 
+0

除了根本不使用'DailyClosePice'(sic),並且你的字典中的值是一個'字符串'而不是一個數字... –

+0

謝謝@JonSkeet。我編輯了答案。 – CodingYoshi

+0

我不會親自使用'DateTime'作爲那裏的關鍵 - 鑑於它是以非常特定的格式(這可能不是默認的文化格式),所以最好直接進行解析。我也建議不要使用浮動貨幣值。 (雖然它是JSON中的一個數值,但在很多平臺上已經可能被視爲'double'了......) –