对象属性的深度计数

Deep count for object properties

我想计算对象中属性的数量。 我已经找到了几个解决方案,但 none 确实计算了 child\nested 属性。

例如,我有以下 JSON 对象。

{
        "id": "259a36d2-3852-425f-a70c-3f9477753210",
        "name": "foo",
        "type": "na",
        "text": "ABC.pdf",
        "left": 333,
        "top": 130,
        "w": 134,
        "h": 34,
        "customData": {
            "A": "fa6css4ec8-8ffb-55bca4dde06a",
            "name": "SDF.pdf",
            "IsExists": false,
            "PNumber": 1,
        }
    }

尝试以下操作时,我得到的结果是 9,而我期望的是 12(这是整个属性的计数)。

JObject sourceJObject = JsonConvert.DeserializeObject<JObject>(json);
var res= sourceJObject.Count;

有助手我会很高兴

JObject.Countdocumented 作为返回 child 个令牌的计数 - 而不是 所有后代 个令牌。因此,虽然您可能 想要 12,但实际上您不应该 期望 12.

如果要计算所有后代的数量,可以使用sourceJObject.Descendants().Count()。但是,这会给你 13 而不是 12,因为 customData 本身就是一个标记。

如果您想要“值不是对象的所有后代属性”,您可以使用 OfTypeWhere,如下面的代码所示。你可能应该考虑一下你想用数组做什么......

using Newtonsoft.Json.Linq;

string json = File.ReadAllText("test.json");

JObject jobject = JObject.Parse(json);
var properties = jobject.Descendants()
    .OfType<JProperty>()
    .Where(prop => prop.Value is not JObject);

Console.WriteLine($"Count: {properties.Count()}");
foreach (var property in properties)
{
    Console.WriteLine($"{property.Name} = {property.Value}");
}

输出:

Count: 12
id = 259a36d2-3852-425f-a70c-3f9477753210
name = foo
type = na
text = ABC.pdf
left = 333
top = 130
w = 134
h = 34
A = fa6css4ec8-8ffb-55bca4dde06a
name = SDF.pdf
IsExists = False
PNumber = 1

试试这个

    var obj=JObject.Parse(json);
    
    var count=0;
    CountProps(obj, ref count); // count=12

public void CountProps(JToken obj, ref int count)
{
    if (obj is JObject)
        foreach (var property in ((JObject)obj).Properties())
        {
            if (property.Value is JValue) count++;
            if (property.Value is JObject) CountProps(property.Value, ref count);
            if (property.Value is JArray) { count++; CountProps(property.Value, ref count); }
        }
    if (obj.GetType().Name == "JArray")
        foreach (var property in ((JArray)obj))
            if (property is JObject || property is JArray) CountProps(property, ref count);
}