Vinay Sawant
Vinay Sawant

Reputation: 378

How to recursively delete empty keys in json in c# using Newtonsoft?

{"a":1,"b":{"c":{}},"d":{"e":1,"f":{"g":{}}}}

This is a simple json,how to recursively delete empty keys from json so output should be here

{"a":1,"d":{"e":1}}

The thing i tried removeEmptyDocs(token,"{}")

   private void removeEmptyDocs(JToken token, string empty)
        {
            JContainer container = token as JContainer;
            if (container == null) return;

            List<JToken> removeList = new List<JToken>();
            foreach (JToken el in container.Children())
            {
                JProperty p = el as JProperty;
                if (p != null && empty.Contains(p.Value.ToString()))
                {
                    removeList.Add(el);
                }

                removeEmptyDocs(el, empty);
            }

            foreach (JToken el in removeList)
            {

                el.Remove();

            }
        }

Upvotes: 1

Views: 2097

Answers (1)

t3mplar
t3mplar

Reputation: 525

You can't remove tokens while iterating, so you should do it after all empty leaves are collected. Here is the code, it's not optimal, but rather good point to start from. And it it does what's expected

class Program
{
    static void Main(string[] args)
    {
        var json =
           "{'a': 1, 'b': {'c': {}, k: [], z: [1, 3]},'d': {'e': 1,'f': {'g': {}}}}";
        var parsed = (JContainer)JsonConvert.DeserializeObject(json);
        var nodesToDelete = new List<JToken>();

        do
        {
            nodesToDelete.Clear();

            ClearEmpty(parsed, nodesToDelete);

            foreach (var token in nodesToDelete)
            {
                token.Remove();
            }
        } while (nodesToDelete.Count > 0);

    }

    private static void ClearEmpty(JContainer container, List<JToken> nodesToDelete)
    {
        if (container == null) return;

        foreach (var child in container.Children())
        {
            var cont = child as JContainer;

            if (child.Type == JTokenType.Property ||
                child.Type == JTokenType.Object ||
                child.Type == JTokenType.Array)
            {
                if (child.HasValues)
                {
                    ClearEmpty(cont, nodesToDelete);
                }
                else
                {
                    nodesToDelete.Add(child.Parent);
                }
            }
        }
    }
}

Upvotes: 2

Related Questions