Home > OS >  C# merge 2 almost identical JSON objects
C# merge 2 almost identical JSON objects

Time:03-09


A while ago I made a function that merged JSON together.

I had a table looking like this, which in this example has been made by left joining the table 'friends' on the table 'persons':

Id Name FriendName FriendAge
1 Danny Jason 19
1 Danny Cesie 18
2 Jason Danny 19

And it would result in a json object looking like this:

[
  {
    "Id": 1,
    "Name": "Danny",
    "Friends": [
      {
        "Name": "Jason",
        "Age": 19
      },
      {
        "Name": "Cesie",
        "Age": 18
      }
    ]
  },
  {
    "Id": 2,
    "Name": "Jason",
    "Friends": [
      {
        "Name": "Danny",
        "Age": 19
      }
    ]
  }
]

I did this by using the following C# code:

using System;
using System.Data;
using Newtonsoft.Json;

namespace JsonTest
{
    class Program
    {
        private class Result
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public Friend[] Friends { get; set; }
        }

        private class Friend
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        static void Main(string[] args)
        {
            string json = "[{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Jason\",\"FriendAge\":19},{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Cesie\",\"FriendAge\":18},{\"Id\":2,\"Name\":\"Jason\",\"FriendName\":\"Danny\",\"FriendAge\":19}]";
            // Original table from example
            DataTable dt = JsonConvert.DeserializeObject<DataTable>(json);

            // Get distinct values from DataTable
            DataView dv = new DataView(dt);
            DataTable distinct_values = dv.ToTable(true, "Id");

            Result[] result = new Result[distinct_values.Rows.Count];
            int i = 0;
            foreach (DataRow row in distinct_values.Rows)
            {
                // Filter the original table on one Id from the distinct values
                dv.RowFilter = $"Id = {row["Id"]}";
                DataTable temp_dt = dv.ToTable();
                Result temp = new Result();

                // Copy general data over to the temp
                temp.Id = Convert.ToInt32(temp_dt.Rows[0]["Id"].ToString());
                temp.Name = temp_dt.Rows[0]["Name"].ToString();

                Friend[] rows = new Friend[temp_dt.Rows.Count];

                // loop over all the rows and copy the array data over
                int j = 0;
                foreach (DataRow temprow in temp_dt.Rows)
                {
                    rows[j] = new Friend();
                    rows[j].Name = temprow["FriendName"].ToString();
                    rows[j].Age = Convert.ToInt32(temprow["FriendAge"].ToString());
                    j  ;
                }

                // Assign everything to where it it supposed to be
                temp.Friends = rows;
                result[i] = temp;
                i  ;
            }

            Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));

            Console.ReadLine();
        }
    }
}

It works really well. But my question, is there another, cleaner or faster, way to do this entire operation? If so, where can I find this? Thanks in advance.

CodePudding user response:

I would create a model to carry your data easier than using DataTable

public class RequestModel{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FriendName { get; set; }
    public int FriendAge { get; set; }
}

Then you can try to use lambda to make it, using GroupBy method get grouping by Id, Name.

string json = "[{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Jason\",\"FriendAge\":19},{\"Id\":1,\"Name\":\"Danny\",\"FriendName\":\"Cesie\",\"FriendAge\":18},{\"Id\":2,\"Name\":\"Jason\",\"FriendName\":\"Danny\",\"FriendAge\":19}]";
var req = JsonConvert.DeserializeObject<IEnumerable<RequestModel>>(json);
var res= req.GroupBy(x=> new {x.Id,x.Name})
    .Select(x=> new Result{
        Name =x.Key.Name,
        Id = x.Key.Id,
        Friends = x.Select(z=> new Friend(){
            Name = z.FriendName,
            Age =  z.FriendAge
        }).ToArray()
    });
var jsonResult = JsonConvert.SerializeObject(res);
  • Related