Home > Net >  How to remove JSON properties with a specific name from an array of objects?
How to remove JSON properties with a specific name from an array of objects?

Time:11-08

I want to remove JSON properties by a specific "key" but it is not working as I expected. My code hasn't changed a thing.

I did the following

void Start()
{
    var foodlist = new List<Food>()
    {
        new() { name = "Banana", price = 3000 },
        new() { name = "Apple", price = 1000}
    };
    
    // SerializeObject()
    string jasonString = JsonConvert.SerializeObject(foodlist);
    JArray jArray = JArray.Parse(jasonString);

    // Jarray => String  Serialize
    string jarrayString2 = JsonConvert.SerializeObject(jArray);

    foreach (var jObject in jArray.Children<JObject>())
    {
        int indexNum = 0;
        foreach (var jProperty in jObject.Properties())
        {
            if(jProperty.Name == "name")
            {
                jArray.Remove(jArray[indexNum][jProperty.Name]);
                indexNum  ;
            }
        }
    }

    // Check
    string jarrayString = JsonConvert.SerializeObject(jArray);
    print(jarrayString);
}

public class Food
{
    public string name;
    public int price;
}

**The result hasn't changed ** Output [{"name":"Banana","price":3000},{"name":"Apple","price":1000}]

Result that I want [{"price":3000},{"price":1000}]

CodePudding user response:

So there a couple of issues with your code. First and foremost seems to be a bug where you are counting iterations during the foreach loop of the properties and not during the loop of the objects. i.e. You want to remove the property for each item in the array but the property is always at position 0. So for every loop you always remove the object property called "name" at position 0. This can be illustrated by setting the value to null instead of removing it. You will see that your output has the first object with null name but the following objects will remain unchanged.

I've had an attempt at making it work as is but where I've landed is basically just a for loop that does the same as a foreach would, with extra work.

e.g. We can try to fix your initial code as such:

int indexNum = 0;
foreach (var jObject in jArray.Children<JObject>())
{        
    foreach (var jProperty in jObject.Properties())
    {            
        if(jProperty.Name == "name")
        {
            jArray[indexNum][jProperty.Name] = null;
        }
    }
    indexNum  ;
}

This should target the correct property in each object, but it could really be simplified down to something like this:

for (int i = 0; i < jArray.Count; i  )
{
    var jObj = jArray[i] as JObject;
    jObj.Remove("name");
}

And then simplifying that even further we could do it in one simple foreach like this:

foreach (JObject jObj in jArray)
{
    jObj.Remove("name");
}

EDIT: I notice that the top foreach method throws an exception that "Collection was modified; enumeration operation may not execute." and so I've just set the value to null instead of try to remove it. But I'll leave the rest of the answer as is for reference.

  • Related