json 使用Select()从条件为真的列表中获取值

ulydmbyx  于 2022-11-19  发布在  其他
关注(0)|答案(4)|浏览(152)

我有一个JSON数组,我需要从该部分的CustomerId属性所在的属性中获取CustomerId值,我在下面尝试遍历类别,并跳过属性树中没有CustomerId属性的类别

var customerId = "";
    foreach (var category in JObject.Parse(someData)?["categories"])
            {
                val = category?["sections"].FirstOrDefault()
                ?["areas"]?.FirstOrDefault()
                ?["components"]?.
                ?["variables"]?.FirstOrDefault()
                ?["properties"]
                ?["customerId"]?.ToString();

                if (val == null)
                    continue;
                else
                {
                    customerId = val;
                    break;
                }

            }

问题是,这看起来效率很低(可读性较差),因为我想象有一个很好的.Select可以用来获得相同的结果,而不用去forEach元素并检查属性是否为null。
请不要这不是一个问题,我有,这是工作,我只想这样做,在一个更可读的方式使用Select,而不是ForEach
示例JSON数据

{
      "categories": [
        {
          "identifier": "cat1",
          "sections": [
            {
              "identifier": "030615e9-67f9-43ca-a06e-194e7afadccb",
              "properties": {},
              "areas": [
                {
                  "identifier": "1206f27b-d354-4bfa-9b5e-1fe6b4f7cc83",
                  "componenets": [
                    {
                      "identifier": "49e4550f-8001-4d32-b796-a7ad4423e118",
                      "type": "Product",
                      "variables": [
                        {
                          "identifier": "0d260417-fa6d-492b-85f1-dc2565bc4805",
                          "properties": {
                        
                            "description": ""
                            
                          }
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "identifier": "cat2",
          "sections": [
            {
              "identifier": "00b5bfa6-f482-47c2-bdd7-aaac273b7772",
              "properties": {},
              "areas": [
                {
                  "identifier": "1ca9d051-5ec0-45af-84bc-561cd7620efa",
                  "componenets": [
                    {
                      "identifier": "c73b1e52-3acd-4020-8fc5-adfef7d633b4",
                      "type": "Customer",
                      "variables": [
                        {
                          "identifier": "0064e872-5c7f-4ec7-a2d6-e8b35b94bd1d",
                          "properties": {
                            "customerId": { "Text":"MainId",
"Value":"A12123"
}
                          }
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
r7xajy2e

r7xajy2e1#

另一种方法是使用JSON.NET库中的.SelectTokens(您似乎正在使用它)。

var customerId = parsedJson.SelectTokens("$.categories..sections..areas..componenets[?(@.type == 'Customer')]..variables..properties.customerId.Value")
    .FirstOrDefault()?
    .ToString();

这实际上是查找组件具有类型“Customer”和属性“customerId”的第一个条目,并将该customerId作为字符串返回。
严格地说,您不需要类型([?(@.type == 'Customer')])上的查询,但我得到的印象是,这正是您想要的。如果没有它,查询将如下所示:

"$.categories..sections..areas..componenets..variables..properties.customerId.Value"

有关SelectTokens的更多信息,请参阅文档here

jobtbby3

jobtbby32#

如果您想使用与问题中相同的逻辑,可以使用下面的代码。
首先,迭代所有categories,其中selectcustomerId字段的来源。这将产生一个customerId列表,其中一些是null,一些可能有值。
下一个SingleOrDefault从列表中取第一个有值的项,这就是你的string customerId
注意:当json中没有customerId时,customerId将会是null。如果您想要掷回例外状况,而不是使用null,您可以使用First()来取代FirstOrDefault

var customerId = JObject.Parse(someData)?["categories"]
                .Select(category => category?["sections"].FirstOrDefault()
                    ?["areas"]?.FirstOrDefault()?["components"]
                    ?["variables"]?.FirstOrDefault()
                    ?["properties"]
                    ?["customerId"]?.ToString())
                .SingleoOrDefault(customerId => customerId != null);
kiz8lqtg

kiz8lqtg3#

我有一个优化版本:

var pJson = JObject.Parse(someData);
JToken? customerToken = pJson.SelectToken($"$..customerId");
var customerId = customerToken?.ToString();
bakd9h0s

bakd9h0s4#

我首先将JSON解析为对象列表,然后使用Linq获取非空的CusmerId列表。

List<T> arrayItems = jsonBuidler?["categories"].ReadFromJson<List<T>>();
List<string> customerIds = arrayItems
   .Where(_ => CustomerId != null)
   .Select(_ => _.CustomerId);

相关问题