使用 System.Text.Json 展平嵌套字典

Flattening a nested dictionary with System.Text.Json

我正在尝试将依赖于 Newtonsoft.Json 的最后一段代码移植到 System.Text.Json

代码解析 JSON 片段并将其展平。这是由遗留系统生成的,因此我们宁愿尽可能不更改它。

// Comment here including the person who last made a change to the program
[
  // Comment here with the date this value set was changed
  [ "value1", "value2", "value3" ],
  // Comment here with the date this value set was changed
  [ "value1", "value2", "value3" ],
  // Repeat over and over for all data
]

我一直在使用以下代码为 Newtonsoft.Json 解析此内容:

using (var sr = new StreamReader(stream))
{
    var array = JArray.Parse(sr.ReadToEnd());
    var flattened = array.SelectMany(x => x).ToArray();

    foreach (var item in flattened)
        items.Add(item.ToObject<string>());
}

上面的代码提取 JSON 有效负载中的每个值,并将它们放入名为 items.

的列表中

如何使用 System.Text.Json 解析上述格式的 JSON?

你的意思是这样的吗?

var data = JsonSerializer.Deserialize<List<List<string>>>(jsonString, new JsonSerializerOptions { AllowTrailingCommas = true });

var flattenData = data.SelectMany(item => item).ToList();

要将您的代码从 Newtonsoft.Json 转换为 System.Txt.Json,您需要执行以下操作:

首先,我看到您正在从流中阅读。因此,我将按原样将您的示例转储到 JSON 文件中。然后我会将它读入流中。我也在做这个 async:

using (var stream = File.OpenRead("test.json"))
{
    var multiDimentional = await JsonSerializer.DeserializeAsync<string[][]>(
        stream, new JsonSerializerOptions
    {
        AllowTrailingCommas = true,
        ReadCommentHandling = JsonCommentHandling.Skip
    });

    var myArray = multiDimentional.SelectMany(x => x);

    foreach(var i in myArray)
    {
        Console.WriteLine(i);
    }
}

这将输出:

value1
value2
value3
value1
value2
value3

由于您的示例包含注释和尾随逗号,因此我为这些情况添加了例外情况。

如果您不需要此 async,则只需删除 await 并将 DeserializeAsync 更改为 Deserialize,而不是从流中读取,您必须先将它读成一个字符串。所以:

var jsonAsString = File.ReadAllText("test.json");

var multiDimentional = JsonSerializer.Deserialize<string[][]>(
    jsonAsString, new JsonSerializerOptions
{
    AllowTrailingCommas = true,
    ReadCommentHandling = JsonCommentHandling.Skip
});

var myArray = multiDimentional.SelectMany(x => x);

foreach(var i in myArray)
{
    Console.WriteLine(i);
}