Home > Back-end >  Deep count for object properties
Deep count for object properties

Time:03-02

I'd like to count the number of properties within an object. I have found several solutions but none really counts the child\nested propertie.

For instance, I have the following JSON object.

{
        "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,
        }
    }

When trying the following I'm getting the result of 9, while I'm expecting 12 (which is the count of the entire properties).

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

I'll be happy for assistant.

CodePudding user response:

JObject.Count is documented as returning the count of child tokens - not all descendant tokens. So while you may want 12, you shouldn't really expect 12.

If you want the count of all descendants, you can use sourceJObject.Descendants().Count(). However, that will give you 13 rather than 12, because customData itself is a token.

If you want "all descendant properties where the value isn't an object" you can use OfType and Where, as shown in the code below. You should probably think about what you want to do with arrays though...

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

Output:

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

CodePudding user response:

try this

    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);
}
  • Related