art-a-game
art-a-game

Reputation: 133

Remove Json Object in Json Array in c#

I am really new to c# language programming and I have a JSON string:

{
  "Type": "Name",
  "parameters": [
    {
      "A": {
        "type": "string",
        "defaultValue": "key"
      },
      "B": {
        "type": "string",
        "defaultValue": "key"
      },
      "C": {
        "type": "string",
        "defaultValue": "key"
      },
      "D": {
        "type": "string",
        "defaultValue": "autogenerated"
      },
      "E": {
        "type": "string",
        "defaultValue": "autogenerated"
      },
      "F": {
        "type": "dropdown",
        "dropDownItems": [
          "true",
          "false"
        ],
        "defaultValue": "false"
      }
    }
  ]
}

and I want to output the JSON array parameters but without "A", "B" and "C". This JSON File is always changing but it always have this "A", "B" and "C".

Upvotes: 2

Views: 19964

Answers (5)

João Paulo Amorim
João Paulo Amorim

Reputation: 436

Among with the answer of Thierry Prost

namespace Testedouble
{
class Program
{
    static void Main(string[] args)
    {
        var jsonString = @"{
      'Type': 'Name',
     'parameters': [
     {
  'A': {
    'type': 'string',
    'defaultValue': 'key'
  },
  'B': {
    'type': 'string',
    'defaultValue': 'key'
  },
  'C': {
    'type': 'string',
    'defaultValue': 'key'
  },
  'D': {
    'type': 'string',
    'defaultValue': 'autogenerated'
  },
  'E': {
    'type': 'string',
    'defaultValue': 'autogenerated'
  },
  'F': {
    'type': 'dropdown',
    'dropDownItems': [
      'true',
      'false'
        ],
      'defaultValue': 'false'
       }
     }
   ]
 }";

        var values = JsonConvert.DeserializeObject<Foo>(jsonString);
        foreach (var key in new string[] { "A", "B", "C" })
        {
            foreach (var item in values.parameters)
            {
                item.Remove(key);
            }

        }
        Console.WriteLine(JsonConvert.SerializeObject(values));


    }

    public class Foo
    {
        public string Type { get; set; }
        public List<Dictionary<string, object>> Parameters { get; set; }
    }
 }
}

Upvotes: 3

G.Dimov
G.Dimov

Reputation: 2393

I made a small console application that shows the desired result. The flow is as follows:

  • We create the C# classes we need for the given JSON: DropdownInfo, ParameterInfo, ParameterBase, Base. I made them several so you can better extend them as you need.
  • We Deserialize the Object and then modify it the way we want.
var itemsToRemove = new string[] { "A", "B", "C" };

Here we add all the elements, which we don't want to be in the output. In our case, we remove A, B, C - Serialize back the Object to JSON. We use Formatting.Indented, so the result looks better (beautifier, human readable)

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;

namespace JsonExercise
{
    public class JsonExercise
    {
        public static void Main(string[] args)
        {
            var sb = new StringBuilder();
            var line = string.Empty;

            while (!string.IsNullOrWhiteSpace((line = Console.ReadLine())))
            {
                sb.AppendLine(line);
            }

            var json = sb.ToString().Trim();
            var inputObj = JsonConvert.DeserializeObject<Base>(json);

            var resultObj = new
            {
                Type = inputObj.Type,
                Parameters = new List<object>()
            };

            Console.WriteLine("--------------------------------");

            //Here we can give all the Properties, which will be skipped!
            var itemsToRemove = new string[] { "A", "B", "C" };

            var propertiesToAdd = new Dictionary<string, object>();
            foreach (var propertyInfo in typeof(ParameterBase).GetProperties())
            {
                if (!itemsToRemove.Contains(propertyInfo.Name))
                {
                    var propertyValue = (inputObj.Parameters[0]).GetType().GetProperty(propertyInfo.Name).GetValue(inputObj.Parameters[0]);
                    propertiesToAdd.Add($"{propertyInfo.Name}", propertyValue);
                }
            }
            var objToAdd = GetDynamicObject(propertiesToAdd);
            resultObj.Parameters.Add(objToAdd);

            Console.WriteLine("Serializing Object");
            Console.WriteLine(JsonConvert.SerializeObject(resultObj, Formatting.Indented));
        }

        public static dynamic GetDynamicObject(Dictionary<string, object> properties)
        {
            return new MyDynObject(properties);
        }
    }

    public sealed class MyDynObject : DynamicObject
    {
        private readonly Dictionary<string, object> _properties;

        public MyDynObject(Dictionary<string, object> properties)
        {
            _properties = properties;
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return _properties.Keys;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (_properties.ContainsKey(binder.Name))
            {
                result = _properties[binder.Name];
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (_properties.ContainsKey(binder.Name))
            {
                _properties[binder.Name] = value;
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public class Base
    {
        public string Type { get; set; }

        public ParameterBase[] Parameters { get; set; }
    }

    public class ParameterBase
    {
        public ParameterInfo A { get; set; }
        public ParameterInfo B { get; set; }
        public ParameterInfo C { get; set; }
        public ParameterInfo D { get; set; }
        public ParameterInfo E { get; set; }
        public DropdownInfo F { get; set; }
    }

    public class ParameterInfo
    {
        public string Type { get; set; }

        public string DefaultValue { get; set; }
    }

    public class DropdownInfo
    {
        public string Type { get; set; }

        public string DefaultValue { get; set; }

        public string[] DropDownItems { get; set; }
    }
}

The first part of the code with the StringBuilder class is just to read the input(The given JSON).

I will give sample input and output JSON data.

--INPUT--

        {
      "Type": "Name",
      "parameters": [
        {
          "A": {
            "type": "string",
            "defaultValue": "key"
          },
          "B": {
            "type": "string",
            "defaultValue": "key"
          },
          "C": {
            "type": "string",
            "defaultValue": "key"
          },
          "D": {
            "type": "string",
            "defaultValue": "autogenerated"
          },
          "E": {
            "type": "string",
            "defaultValue": "autogenerated"
          },
          "F": {
            "type": "dropdown",
            "dropDownItems": [
              "true",
              "false"
            ],
            "defaultValue": "false"
          }
        }
      ]
    }

--OUTPUT--

{
  "Type": "Name",
  "Parameters": [
    {
      "D": {
        "Type": "string",
        "DefaultValue": "autogenerated"
      },
      "E": {
        "Type": "string",
        "DefaultValue": "autogenerated"
      },
      "F": {
        "Type": "dropdown",
        "DefaultValue": "false",
        "DropDownItems": [
          "true",
          "false"
        ]
      }
    }
  ]
}

Edit: Changed the code after @João Paulo Amorim comment. I tested the code it works fine, use it freely. Shout out to João Paulo Amorim and his answer. Looks smoother.

PS. My first answer on StackOverFlow \o/

Upvotes: 2

er-sho
er-sho

Reputation: 9771

1) Parse your json to JObject under namespace with using Newtonsoft.Json.Linq;

2) Retrieve 1st object inside parameters array by using JObject.SelectToken()

3) Remove A, B, C by using JObject.Remove()

string json = "Your json here";

JObject jObject = JObject.Parse(json);

JObject jObj = (JObject)jObject.SelectToken("parameters[0]");
jObj.Property("A").Remove();
jObj.Property("B").Remove();
jObj.Property("C").Remove();

string output = jObject.ToString();

Output: (From Debugger)

enter image description here

Online Demo

Upvotes: 0

Thierry Prost
Thierry Prost

Reputation: 1025

Using newtonsoft library

Working Fiddle added

public class Foo
{
  public string Type { get; set; }
  [JsonProperty("parameters")]
  public List<Dictionary<string, object>> Parameters { get; set; }
  [JsonProperty("defaultValue")]
  public string DefaultValue { get; set; }

}
var values = JsonConvert.DeserializeObject<Foo>(jsonStr);
values.Parameters = values
    .Parameters
    .Select(
        dic => dic
            .Where(kvp => new string[] { "A", "B", "C" }.Contains(kvp.Key))
            .ToDictionary(kvp => kvp.Key, kvp => kvp.Value))
    .ToList();
Console.WriteLine(JsonConvert.SerializeObject(values));

Upvotes: 0

user8689373
user8689373

Reputation: 125

With Newtonsoft.Json package:

using System;
using Newtonsoft.Json;
using System.IO;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
          //File with json
          string jsontext = File.ReadAllText("json.json");

          dynamic json = JsonConvert.DeserializeObject(jsontext);
          foreach(var parameter in json.parameters)
          {
            Console.WriteLine(parameter.D);
            Console.WriteLine(parameter.E);
            Console.WriteLine(parameter.F);
          }
          Console.ReadLine();
        }
    }
}

Upvotes: 0

Related Questions