使用Json.NET在C#中计算JSON字符串中元素的数量

16

我有一个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。有时我可能只有一个package,在这种情况下,我希望它返回整数1。其他时候我可能有20个包(在这种情况下我希望它返回20)。

我的JObject长这样:

JObject o = JObject.Parse(myJsonString);
任何想法?感谢任何帮助。
6个回答

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

BONUS:

dynamic jObj = JsonConvert.DeserializeObject(myJsonString);

foreach (var package in jObj)
{
    Console.WriteLine("{0} {1}", package.First.type, package.First.quantity);
}

1
非常感谢!这让我疯狂了好几天。我会在4分钟内将其标记为正确 :) - Brent Barbata
哈,我在阅读推荐的24-48小时等待期之前就接受了它。我是新手,还在学习中。无论如何,再次感谢您的帮助。 - Brent Barbata
@BrentBarbata 如果你可以使用dynamic,你会得到奖金。 - L.B
第二种方式对于我最终想要做的事情甚至更有效。非常感谢! - Brent Barbata

0

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

JsonConvert.DeserializeObject<IDictionary>(myJsonString).Count

或者

JsonConvert.DeserializeObject<IDictionary<string, object>>(myJsonString).Count

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或更高,因为dynamic关键字是在那个时候添加的。


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


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());
}

希望能有所帮助。


-2
在 JQuery 的 $.ajax 中,你会收到一个数组,遍历其中的元素并得到它们的总和。

非常感谢您的回复,但我正在尝试使用C#中的Json.NET来解决这个问题。 - Brent Barbata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接