gpt4 book ai didi

c# - 使用 Linq、JSON.NET、C# 查询 JSON 嵌套数组

转载 作者:行者123 更新时间:2023-11-30 19:37:17 25 4
gpt4 key购买 nike

这篇文章是为了提出与我最近的另一篇文章 (Picking Out Simple Properties from Hierarchical JSON Part II) 相关的更直接的问题:

给定嵌套的 JSON 文档,如下所示:

{
"Array1": {
"Array1A": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
],
"Array1B": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
]
},
"Array2": {
"Array2A": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
]
},
"Array3": {
"Array3A": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
],
"Array3B": [
{ "Item1": "1" },
{ "Item2": "2" },
{
"Array3B1": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
]
}
],
"Array3C": [
{ "Item1": "1" },
{ "Item2": "2" },
{ "Item3": "3" }
]
}
}

(注意:以上是使用 JSLint 验证的。)

请注意,JSON 是动态的——我事先不知道会有多少数组或数组嵌套的深度。

目标:我的目标是在 List<JObject> 中表示每个数组(即 Array1、Array2、Array3、Array3A、Array3B 和 Array3B1)。目的。列表中的每一项都是 JProperty 对象的集合,其中包含该数组的字符串属性。因为 List 本身不对分层数据建模,所以我需要为每个 List<JObject> 添加一个综合属性。引用该数组父项的项。因此,Array1 的父级是一个空字符串; Array2就是Array1,Array3就是Array2,Array3A就是Array3,Array3B就是Array3,Array3B1就是Array3B...

问题:1. 如何使用 C# Linq 创建 List<JObject>看起来像这样的对象:

list[0]: 
{"Name":"Array1","Parent":""}

list[1]:
{"Name":"Array1A","Item1":"1","Item2":"2","Item3":"3","Parent":"Array1"}

list[2]:
{"Name":"Array1B","Item1":"1","Item2":"2","Item3":"3","Parent":"Array1"}

list[3]:
{"Name":"Array2","Parent":""}

list[4]:
{"Name":"Array2A","Item1":"1","Item2":"2","Item3":"3","Parent":"Array2"}

list[5]:
{"Name":"Array3","Parent":""}

list[6]:
{"Name":"Array3A","Item1":"1","Item2":"2","Item3":"3","Parent":"Array3"}

list[7]:
{"Name":"Array3B","Item1":"1","Item2":"2","Parent":"Array3"}

list[8]:
{"Name":"Array3B1","Item1":"1","Item2":"2","Item3":"3","Parent":"ArrayB"}

list[9]:
{"Name":"Array3C","Item1":"1","Item2":"2","Item3":"3","Parent":"Array3"}

请注意:

  • 每个List<JObject>仅包含字符串属性。
  • 在列表 [7] 中,缺少 Item2 之后的 JSON 标记,因为它是一个数组。相反,该项目在列表 [8] 中用正确的父引用表示。

最佳答案

这样的事情怎么样:

List<JObject> list = 
JObject.Parse(json)
.Descendants()
.Where(jt => jt.Type == JTokenType.Property && ((JProperty)jt).Value.HasValues)
.Cast<JProperty>()
.Select(prop =>
{
var obj = new JObject(new JProperty("Name", prop.Name));
if (prop.Value.Type == JTokenType.Array)
{
var items = prop.Value.Children<JObject>()
.SelectMany(jo => jo.Properties())
.Where(jp => jp.Value.Type == JTokenType.String);
obj.Add(items);
}
var parentName = prop.Ancestors()
.Where(jt => jt.Type == JTokenType.Property)
.Select(jt => ((JProperty)jt).Name)
.FirstOrDefault();
obj.Add("Parent", parentName ?? "");
return obj;
})
.ToList();

fiddle :https://dotnetfiddle.net/FMxzls

如果您不太熟悉 LINQ-to-JSON ,它是这样分解的:

  1. 将json字符串解析成JObject

    JObject.Parse(json)
  2. 从那个 JObject 获取它的所有后代 JTokens

           .Descendants()
  3. 将该列表过滤为仅具有其值具有子项的 JProperties

           .Where(jt => jt.Type == JTokenType.Property && ((JProperty)jt).Value.HasValues)
  4. 将 JTokens 转换为 JProperties,使它们在下一步中更易于使用

           .Cast<JProperty>()
  5. 现在,对于我们选择的每个 JProperty,按如下方式转换它:

           .Select(prop =>
    {
  6. 创建一个新的 JObject 并将 JProperty 的名称添加为新对象的 Name 属性

               var obj = new JObject(new JProperty("Name", prop.Name));
  7. 如果 JProperty 的值是一个数组...

               if (prop.Value.Type == JTokenType.Array)
    {
  8. 获取数组的所有直接子对象,它们是 JObjects

                   var items = prop.Value.Children<JObject>()
  9. 从那些 JObjects 中,获取所有的 JProperties

                                         .SelectMany(jo => jo.Properties())
  10. 过滤那些 JProperties 以仅包含其值为字符串的 JProperties)

                                         .Where(jp => jp.Value.Type == JTokenType.String);
  11. 将这些项目的 JProperties 添加到我们之前创建的新 JObject

                    obj.Add(items);
    }
  12. 接下来,找到当前JProperty的第一个祖先JProperty,并得到它的名字

                var parentName = prop.Ancestors()
    .Where(jt => jt.Type == JTokenType.Property)
    .Select(jt => ((JProperty)jt).Name)
    .FirstOrDefault();
  13. 将父名称添加到我们正在构建的 JObject 中;如果没有父级,则使用空字符串

                obj.Add("Parent", parentName ?? "");
  14. 继续下一个转换

                return obj;
    })
  15. 最后将我们构建的所有 JObjects 放入一个列表中。

            .ToList();

关于c# - 使用 Linq、JSON.NET、C# 查询 JSON 嵌套数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38622957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com