【问题标题】:Linq in JSON.NETJSON.NET 中的 Linq
【发布时间】:2016-06-30 12:16:10
【问题描述】:

我有一个json字符串如下

{
    'Sheet1': [{
        'EmployeeNo': '123456',
        'EmployeeName': 'Midhun Mathew'
    }, {
        'EmployeeNo': '123457',
        'EmployeeName': 'Bill Gates'
    }, {
        'EmployeeNo': '123456',
        'Address': 'AAAA'
    }, {
        'EmployeeNo': '123457',
        'Address': 'BBBB'
    }]
}
JObject parsedJson = JObject.Parse(jsonString);

// Get the EmployeeNo's 

List<JToken> tokenList = parsedJson["Sheet1"]
                           .GroupBy(d => d["EmployeeNo"])
                           .Select(s => s.Key)
                           .ToList();

// Get the tokens which have the Same 'EmployeeNo'

foreach (JToken j in tokenList)
{
    IEnumerable<JToken> t = parsedJson["Sheet1"].Where(s => s["EmployeeNo"] == j);
}

但在 foreach 中我只得到第一个

{
  "EmployeeNo": "123456",
  "EmployeeName": "Midhun Mathew"
}

我没有明白我在这里做错了什么。

我的初衷是将具有相同 EmployeeNo 的 JToken 归为一个 JObject

所以在上述情况下,我将获得 2 个 JObject,因为有 2 个不同的 EmployeeNo

希望我清楚

【问题讨论】:

  • 用 firstordeafult 替换你的 forloop 代码对我有用..var t = parsedJson["Sheet1"].FirstOrDefault(s => s["EmployeeNo"] == j);
  • var tokenList = parsed["Sheet1"] .OrderBy(o =&gt; o["EmployeeNo"]) .SelectMany(grp =&gt; grp.Skip(1));

标签: c# json linq json.net


【解决方案1】:

尚不完全清楚您要在这里做什么,但您似乎是按EmployeeNo 分组,然后丢弃结果以仅获取键,然后尝试在更手动的情况下再次进行分组方式。

如果您删除 Select(s =&gt; s.Key) 部分,那么您可以直接使用分组:

var tokensByEmployeeNo = parsedJson["Sheet1"].GroupBy(x => x["EmployeeNo"]);

foreach (var grouping in tokensByEmployeeNo)
{
    Console.WriteLine($"Key: {grouping.Key}");

    foreach (var token in grouping)
    {
        Console.WriteLine(token);
    }            
}

如果您想为这些分组中的每一个创建一个“新”JObject,那么您可能希望为每个组创建一个 JArray

var groupedArrays = parsedJson["Sheet1"]
    .GroupBy(x => x["EmployeeNo"])
    .Select(groupedRecords => new JArray(groupedRecords));

第一个看起来像这样,例如:

[
  {
    "EmployeeNo": "123456",
    "EmployeeName": "Midhun Mathew"
  },
  {
    "EmployeeNo": "123456",
    "Address": "AAAA"
  }
]

【讨论】:

  • 感谢您的回答。你的理解是对的。但我希望它作为 JToken 而不是 var,以便我可以将 var 中的值添加到单独的 jObjects 中。这里可以吗?
  • 我不确定我是否理解您的意思。 grouping 在这种情况下实现 IEnumerable&lt;JToken&gt; - 这与您在问题中的返回类型相同。内部循环中的token 变量的类型为JToken
  • 我尝试更改为 IEnumerable&lt;JToken&gt; jt = (IEnumerable&lt;JToken&gt;)parsedJson["Sheet1"].GroupBy(x =&gt; x["EmployeeNo"]); 但我收到异常消息:无法转换类型为“System.Linq.GroupedEnumerable3[Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Linq.JToken]' to type 'System.Collections.Generic.IEnumerable1[Newtonsoft.Json.Linq.JToken]”的对象。真的很抱歉这些愚蠢的问题。我是新手。这就是为什么。
  • @MidhunMathew 我已经更新了我的答案,以展示您如何为每个组创建一个JArray
  • @MidhunMathew 很高兴听到。确实发生了这可能不是您所追求的,我认为您可能想要一个具有 3 个属性(EENo、名称和地址)的JObject
【解决方案2】:

如果您只是想查看员工列表,我习惯这样做:

   var json = @"
                        {
                'Sheet1': [{
                    'EmployeeNo': '123456',
                    'EmployeeName': 'Midhun Mathew'
                }, {
                    'EmployeeNo': '123457',
                    'EmployeeName': 'Bill Gates'
                }, {
                    'EmployeeNo': '123456',
                    'Address': 'AAAA'
                }, {
                    'EmployeeNo': '123457',
                    'Address': 'BBBB'
                }]
            }";

            var array = JArray.Parse(JObject.Parse(json).SelectToken("Sheet1").ToString());

            foreach (var arrayElement in array)
            {
                var employeeNo = JObject.Parse(arrayElement.ToString()).SelectToken("EmployeeNo");
                var employeeName = JObject.Parse(arrayElement.ToString()).SelectToken("EmployeeName");

                Console.WriteLine("Number: {0}, Name: {1}", employeeNo, employeeName);
            }

输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2023-03-24
    • 2010-11-27
    • 1970-01-01
    相关资源
    最近更新 更多