我使用以下内容反序列化一些嵌套的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);
完成此操作后,每个字典键的值可能是另一个字典,依此类推,多个级别深。
我想要做的是展平多级数据,这样它只是一个扁平的数组/列表,只包含所有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 :(得分:5)
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();
答案 1 :(得分: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())
。