2

次のように、ネストされた 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 を使用しています。

4

2 に答える 2

7
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();
于 2012-09-13T09:13:07.527 に答える
4

ここで再帰が必要です:

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();

KeyValuePair<string, string>.NET 3.5 では、代わりに を使用できますTuple<string, string>

がないことに注意してください。代わりKeyValuePair.Createに使用する必要があります。new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())

于 2012-09-13T08:57:43.370 に答える