Xynado
Xynado

Reputation: 11

Combine 2 JSON strings with a common key c#

I'm trying to figure out in C# how to combine 2 JSON strings that I get back from 2 different sources and combine them together into 1 Json result.

First JSON

[{
    "UserId": 1,
    "FirstName": "John",
    "LastName": "Doe",
    "Email": "[email protected]"
}]

Second JSON

 [{
    "UserId": 1,
    "AccountName": "JDOE"
}]

Result

[{
    "UserId": 1,
    "FirstName": "John",
    "LastName": "Doe",
    "Email": "[email protected]",
    "AccountName": "JDOE"
}]

Been Messing with the following code not able to get the expect results

 JArray o1 = JArray.Parse(@"[{'FirstName': 'John2',
                                         'LastName': 'Doe2',
                                         'UserID': '2'},
                                        {'FirstName': 'John1',
                                         'LastName': 'Doe1',
                                         'UserID': '1'}]");
            JArray o2 = JArray.Parse(@"[{'UserID': '1',
                                        'AccountName': 'JD1'},
                                        { 'UserID': '2',  
                                          'AccountName': 'JD2'}]");

            o1.Merge(o2, new JsonMergeSettings
            {
                // union array values together to avoid duplicates
                MergeArrayHandling = MergeArrayHandling.Merge
            });


            string json = o1.ToString();

it gives the following results

{[
  {
    "FirstName": "John2",
    "LastName": "Doe2",
    "UserID": "1",
    "AccountName": "JD1"
  },
  {
    "FirstName": "John1",
    "LastName": "Doe1",
    "UserID": "2",
    "AccountName": "JD2"
  }
]}

Im trying to match the user info with with account info by the userid key, I'm trying to get something like this(basically a left join on UserID is what I need)

{[
  {
    "FirstName": "John1",
    "LastName": "Doe1",
    "UserID": "1",
    "AccountName": "JD1"
  },
  {
    "FirstName": "John2",
    "LastName": "Doe2",
    "UserID": "2",
    "AccountName": "JD2"
  }
]}

Upvotes: 1

Views: 1056

Answers (2)

Anh Lai
Anh Lai

Reputation: 367

When you use MergeArrayHandling = MergeArrayHandling.Union will return this:

[
  {
    "FirstName": "John2",
    "LastName": "Doe2",
    "UserID": "2"
  },
  {
    "FirstName": "John1",
    "LastName": "Doe1",
    "UserID": "1"
  },
  {
    "UserID": "1",
    "AccountName": "JD1"
  },
  {
    "UserID": "2",
    "AccountName": "JD2"
  }
]

and need to handle more to get expected result: Here is my result after run my code:

[
  {
    "FirstName": "John2",
    "LastName": "Doe2",
    "UserID": "2",
    "AccountName": "JD2"
  },
  {
    "FirstName": "John1",
    "LastName": "Doe1",
    "UserID": "1",
    "AccountName": "JD1"
  }
]

Below is my solution:

            JArray o1 = JArray.Parse(@"[{'FirstName': 'John2',
                                         'LastName': 'Doe2',
                                         'UserID': '2'},
                                        {'FirstName': 'John1',
                                         'LastName': 'Doe1',
                                         'UserID': '1'}]");
            JArray o2 = JArray.Parse(@"[{'UserID': '1',
                                        'AccountName': 'JD1'},
                                        { 'UserID': '2',  
                                          'AccountName': 'JD2'}]");

            o1.Merge(o2, new JsonMergeSettings
            {
                // union array values together to avoid duplicates
                MergeArrayHandling = MergeArrayHandling.Union
            });
            var jArray = new JArray();
            var groupedByUserID = o1.GroupBy(x => x["UserID"]).ToList();
            foreach (var item in groupedByUserID)
            {
                var firstToken = item.First();
                var remainingToken = item.Values().Except(firstToken);
                foreach (var i in remainingToken)
                {
                    if (i.Type == JTokenType.Property)
                        firstToken[((JProperty)i).Name] = ((JProperty)i).Value;
                }
                jArray.Add(firstToken);
            }
            var result = jArray.ToString(Formatting.Indented);

Upvotes: 0

Rui Caramalho
Rui Caramalho

Reputation: 483

If you are using ´Newtonsoft.Json´, and you should, just do the example bellow

JObject o1 = JObject.Parse(@"{
  'FirstName': 'John',
  'LastName': 'Smith',
  'Enabled': false,
  'Roles': [ 'User' ]
}");
JObject o2 = JObject.Parse(@"{
  'Enabled': true,
  'Roles': [ 'User', 'Admin' ]
}");

o1.Merge(o2, new JsonMergeSettings
{
    // union array values together to avoid duplicates
    MergeArrayHandling = MergeArrayHandling.Union
});

reference: https://www.newtonsoft.com/json/help/html/MergeJson.htm

Upvotes: 3

Related Questions