Navigating or transforming JSON with Linq

huangapple go评论67阅读模式
英文:

Navigating or transforming JSON with Linq

问题

{
  "data": "014",
  "theme": "COLORADO CASUAL",
  "family": "2163",
  "category": "00",
  "compo_groups": [
    {
      "title": "HEAD024",
      "values": [
        {
          "perc": "100",
          "desc": "COMP036"
        }
      ]
    },
    {
      "title": "HEAD035",
      "values": [
        {
          "perc": "100",
          "desc": "COMP042"
        },
        {
          "perc": "50",
          "desc": "COMP043"
        }
      ]
    }
  ],
  "product_name": "D812",
  "supplier_code": "1011"
}

我需要检查所有的组合是否恰好为100%。在这个JSON中,我有2组组合。第一个是正确的,有一个元素占100%。第二个由2个元素组成,总共是150%。这是一个错误。

我需要在C#中编写代码来检测错误。我可以编写大部分的代码,只是不知道如何将这个JSON转化为我可以使用LinQ进行处理的值列表。


<details>
<summary>英文:</summary>

Let consider this JSON 

```json
{
  &quot;data&quot;: &quot;014&quot;,
  &quot;theme&quot;: &quot;COLORADO CASUAL&quot;,
  &quot;family&quot;: &quot;2163&quot;,
  &quot;category&quot;: &quot;00&quot;,
  &quot;compo_groups&quot;: [
    {
      &quot;title&quot;: &quot;HEAD024&quot;,
      &quot;values&quot;: [
        {
          &quot;perc&quot;: &quot;100&quot;,
          &quot;desc&quot;: &quot;COMP036&quot;
        }
      ]
    },
    {
      &quot;title&quot;: &quot;HEAD035&quot;,
      &quot;values&quot;: [
        {
          &quot;perc&quot;: &quot;100&quot;,
          &quot;desc&quot;: &quot;COMP042&quot;
        },
        {
          &quot;perc&quot;: &quot;50&quot;,
          &quot;desc&quot;: &quot;COMP043&quot;
        }
      ]
    }
  ],
  &quot;product_name&quot;: &quot;D812&quot;,
  &quot;supplier_code&quot;: &quot;1011&quot;
}

I need to check that all my compositions are exactly 100pc. In this JSON I have 2 group of composition. The first one is correct. I have one element to 100pc. The second one is composed by 2 elements and total is 150pc. This is an error.

I need to write a code in C# that detect the error. I can write most part of this code. I just don't know how to transform this JSON in list of values I can manage with LinQ.

答案1

得分: 4

假设您正在使用最新版本的.NET(例如.NET6),那么您可以使用内置的System.Text.Json库来解析您的JSON输入。如果您需要使用JSON的其他部分,我建议将其反序列化为具体的C#类,以便获得适当的验证、智能感知以及所有这些好东西。

然而,如果您只是想检查这些百分比,您可以直接使用STJ库,例如:

// 加载JSON 
var json = "{...}";
var doc = JsonDocument.Parse(json);

// 手动遍历文档以获取所需的值并汇总
var result = doc.RootElement
    .GetProperty("compo_groups")
    .EnumerateArray()
    .Select(a => new 
    {
        Title = a.GetProperty("title").ToString(),
        Percentage = a.GetProperty("values")
            .EnumerateArray()
            .Select(v => double.Parse(v.GetProperty("perc").ToString()))
            .Sum()
    });

然后,您可以像这样遍历该结果:

foreach(var value in result)
{
    Console.WriteLine($"Title '{value.Title}' has a percentage of {value.Percentage}");
}

这将输出以下内容:

Title 'HEAD024' has a percentage of 100
Title 'HEAD035' has a percentage of 150
英文:

Assuming you are using a recent version of .NET (e.g. .NET6) then you can use the built-in System.Text.Json libraries to parse your JSON input. If you need to use other parts of the JSON, I would recommend deserialising in to concrete C# classes so you get proper validation, IntelliSense and all that good stuff.

However, if you simply want to check those percentages you can use the STJ library directly, something like this for example:

// Load JSON 
var json = &quot;{...}&quot;;
var doc = JsonDocument.Parse(json);

// Manually walk the document to get the values you need and summarise
var result = doc.RootElement
	.GetProperty(&quot;compo_groups&quot;)
	.EnumerateArray()
	.Select(a =&gt; new 
	{
    	Title = a.GetProperty(&quot;title&quot;).ToString(),
		Percentage = a.GetProperty(&quot;values&quot;)
			.EnumerateArray()
			.Select(v =&gt; double.Parse(v.GetProperty(&quot;perc&quot;).ToString()))
			.Sum()
	});

And you can iterate over that result like this:

foreach(var value in result)
{
	Console.WriteLine($&quot;Title &#39;{value.Title}&#39; has a percentage of {value.Percentage}&quot;);
}

Which will output this:

Title &#39;HEAD024&#39; has a percentage of 100
Title &#39;HEAD035&#39; has a percentage of 150

答案2

得分: 3

以下是翻译好的部分:

不需要任何类来获取您想要的数据

or

不需要任何类来获取您想要的数据
英文:

you don't need any classes to get the data you want

using System.Text.Json;

List&lt;string&gt; titles = JsonNode.Parse(json)[&quot;compo_groups&quot;].AsArray()
						 .Select(x =&gt; x[&quot;values&quot;].AsArray())
						 .Where(v =&gt; v.Select(x =&gt; 
                          Convert.ToInt32(x[&quot;perc&quot;].GetValue&lt;string&gt;())).Sum() &gt; 100)
						 .Select(v =&gt; v.Parent[&quot;title&quot;].GetValue&lt;string&gt;())
						 .ToList();  // result  [&quot;HEAD035&quot;]

or

using Newtonsoft.Json;

List&lt;string&gt; titles = JObject.Parse(json)[&quot;compo_groups&quot;]
	.Select(x =&gt; x[&quot;values&quot;])
	.Where(v =&gt; v.Select(x =&gt; (int)x[&quot;perc&quot;]).Sum() &gt; 100)
	.Select(v =&gt; v.Parent.Parent)
    .Select(p=&gt; (string) p[&quot;title&quot;]) // here you can select any data you need
	.ToList();  // result  [&quot;HEAD035&quot;]

huangapple
  • 本文由 发表于 2023年2月14日 20:02:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447562.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定