12

我有一个如下所示的 JSON 字符串:

{
"package1": {
    "type": "envelope",
    "quantity": 1,
    "length": 6,
    "width": 1,
    "height": 4
},
"package2": {
    "type": "box",
    "quantity": 2,
    "length": 9,
    "width": 9,
    "height": 9
}
}

我正在使用 Json.NET LINQ to JSON 功能来处理我的 JSON 字符串,但我想知道如何在我的细绳。例如,上面的字符串有 package1 和 package2,所以我想知道如何让它返回整数 2。有时我可能只有一个包,在这种情况下,我希望它返回整数 1。其他有时我可能有 20 个包裹(在这种情况下,我希望它返回 20 个)。

我的 JObject 看起来像这样:

JObject o = JObject.Parse(myJsonString);

有任何想法吗?谢谢你的帮助。

4

6 回答 6

27
JObject jObj = (JObject)JsonConvert.DeserializeObject(myJsonString);
int count = jObj.Count;

奖金:

dynamic jObj = JsonConvert.DeserializeObject(myJsonString);

foreach (var package in jObj)
{
    Console.WriteLine("{0} {1}", package.First.type, package.First.quantity);
}
于 2012-04-03T20:55:26.777 回答
0

递归版本(计算所有具有原始值的属性)

遇到这个问题试图用谷歌搜索 JObject 值的递归计数,没有找到很多其他问题,所以我想我也会将我想出的内容添加到这个问题中

int CountJTokenProperties(JToken token)
{
    var sum = 0;

    if (token.Type == JTokenType.Object)
    {
        foreach (var child in token.Value<JObject>())
        {
            sum += CountJTokenProperties(child.Value);
        }
    }
    else if (token.Type == JTokenType.Array)
    {
        foreach (var child in token.Value<JArray>())
        {
            sum += CountJTokenProperties(child);
        }
    }
    else
    {
        sum += 1;
    }

    return sum;
}

和可能有更好的选择.Value<JObject>().Value<JArray>()但这似乎有效。

特别是我想要一个具有可变样本数据的 nunit 测试,并希望确保它正确反序列化。决定一个简单的检查方法是 C# 对象上有多少非默认值,并且 JsonConvert 具有这种能力:

public int CountNonDefaultProperties(object obj)
{
    // Let JsonConvert do the work of stripping out default values
    var serialized = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
    {
        DefaultValueHandling = DefaultValueHandling.Ignore
    });

    // Recurse into the json structure, which is much simpler than C# Object structure
    var jObj = JObject.Parse(serialized);

    return CountJTokenProperties(jObj);
}

请注意,DefaultValueHandling.Ignore保留作为数组一部分的默认值,因此如果您想要该功能,您需要以不同的方式或其他方式计算数组项,此活动留给读者

https://dotnetfiddle.net/XIZCvh

于 2018-07-08T18:33:58.407 回答
0

使用Cinchoo ETL - 一个开源库,您可以使用更少的内存开销轻松地进行节点计数,因为它使用流式方法来解析输入。因此它也可以处理大文件。

string json = @"{
""package1"": {
""type"": ""envelope"",
""quantity"": 1,
""length"": 6,
""width"": 1,
""height"": 4
},
""package2"": {
""type"": ""box"",
""quantity"": 2,
""length"": 9,
""width"": 9,
""height"": 9
}
}";

using (var p = ChoJSONReader.LoadText(json).WithJSONPath("$.*"))
{
    Console.WriteLine(p.Count());
}

希望能帮助到你。

于 2018-07-08T22:24:56.947 回答
0
 string json= "{
"package1": {
"type": "envelope",
"quantity": 1,
"length": 6,
"width": 1,
"height": 4
 },
 "package2": {
 "type": "box",
 "quantity": 2,
 "length": 9,
 "width": 9,
 "height": 9
 }
 }"; 

 dynamic stuff;
 int count;
 stuff = JsonConvert.DeserializeObject(json);
 foreach(JProperty s in stuff){

  count++;
  }

  Console.WriteLine(count.ToString());

如果 Count 属性不适合您,请改用此方法。确保您的 C# 版本为 4.0 或更高版本,因为当时添加了动态关键字。

于 2020-03-06T08:40:10.443 回答
0

对字典类型使用反序列化:

JsonConvert.DeserializeObject<IDictionary>(myJsonString).Count

或者

JsonConvert.DeserializeObject<IDictionary<string, object>>(myJsonString).Count
于 2021-12-02T15:11:32.067 回答
-2

在 JQuery $.ajax 中,您将收到一个数组,遍历元素并获得总和。

于 2012-04-03T20:50:55.140 回答