2012-09-13 57 views
1

我反序列化一些嵌套JSON具有以下:平鋪嵌套字典<串,對象>

string json = @"{ 
    ""name"": ""charlie"", 
    ""someID"": 123, 
    ""level1"" : { 
     ""name"": ""charlie 1"", 
     ""someID"": 456 
    } 
}"; 

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Dictionary<string, object> data = serializer.Deserialize<Dictionary<string, object>>(json); 

一旦做到這一點,每個字典鍵的值可以是另一字典,等等,多個級別深。

我想要做的是平坦化多級數據所以它只是一個扁平的Array/List,只有所有的JSON屬性名稱和它們的值。所以,我最終的東西是這樣的:

name, "charlie" 
someID, 123 
name, charlie 1 
someID, 456 

我標題下使用的SelectMany(路徑)等等,但不能爭吵它做什麼我之後。

我已經有點事情蹣跚圍繞這樣的:

var obj = data.Values.SelectMany<object, Dictionary<string, object>>(x => x); 

但我不能夠滿足編譯器。是的,我迷路了。

我正在使用.NET 3.5。

+0

創建自己的對象與每個屬性 –

回答

3
Func<Dictionary<string, object>, IEnumerable<KeyValuePair<string, object>>> flatten = null; 

flatten = dict => dict.SelectMany(kv => 
         kv.Value is Dictionary<string,object> 
          ? flatten((Dictionary<string,object>)kv.Value) 
          : new List<KeyValuePair<string,object>>(){ kv} 
         ); 

var flatList = flatten(data).ToList(); 
3

您需要遞歸這裏:

IEnumerable<Tuple<string, string>> Flatten(this IDictionary dict) 
{ 
    foreach(DictionaryEntry kvp in dict) 
    { 
     var childDictionary = kvp.Value as IDictionary; 
     if(childDictionary != null) 
     { 
      foreach(var tuple in childDictionary.Flatten()) 
       yield return tuple; 
     } 
     else 
      yield return Tuple.Create(kvp.Key.ToString(), kvp.Value.ToString()); 
    } 
} 

// Usage: 

var flatList = data.Flatten().ToList(); 

在.NET 3.5中,可以使用KeyValuePair<string, string>而不是Tuple<string, string>

請注意,沒有KeyValuePair.Create,您需要使用new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())來代替。

+0

丹尼爾,看起來不錯。不幸的是,我使用的是.NET 3.5,這意味着Tupkes不在了。抱歉。 – dbarros

+0

@dbarros:您可以改用KeyValuePair。 –

+0

+1我幾乎在LinqPad中使用相同的代碼(只是使用KeyValuePairs),但我太慢了.... :-) – sloth

相關問題