Compare Json Collection, return change values - c#

I have Json Collection with the different fields. All fields are dynamic. Please take the below example.
[{"KB":"1","Id":"01","MemCode":1,"A":"2","B":"1","C":"2010-01-01T00:00:00","D":1}
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","C":"2010-01-01T00:00:00","D":2},
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","C":"2010-01-01T00:00:00","D":3},
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","C":"2010-01-01T00:00:00","D":4}]
I want to compare Four number json with the first one and identify the changes,
Like in fourth line Memcode is 2 and in first Memcode is 1. So here memcode is change from 2 to 1.
Like wise for all the fields. this field may be any type like datetime/ string etc. This is just example. JSON may be long with many fields. But all json string is same fields.
All fields are dynamic. I want some method which do above calculation and return field change with the old and new values.
I want to do using C# and Newtonsoft.Json. I don't know how to achieve above one. Can you please help me/guide me?
Thank you in advance.
EDIT :- 5/10
Hello, Sorry If I am not clear. Let me Explain Once again. I want develop some generic method who accept the collection of the JSON. This JSON have a number of different fields.
Suppose Collection have a 5 JSON. ALl 5 JSON have a same number of fields with a different value or may be same values.
Now I want to compare 1st number of JSON with the N number of JSON. Identify which field has been changes. Take that field and it's old value/New value in the Collection. Old value will be N field value and New value will be 1 field value. Continue this way for other JSON. Now 1st Number JSON compare with the N-1. and identify change fields. Continue this way up to all collection finished.
Return value be Fields and Old value, New value.
The field can by string, number of date.
I can do using for loop but I want some generic method which is time efficient and align with the new C# feature.
Hope I am clear this time.
Thank you so much..

Use dynamic and convert your Json object as bellow
dynamic data= JsonConvert.DeserializeObject(your Json Object);
Then use normal foreach loop on data to compare

You could convert each JSON object to List<string> where string represents one or more JSON attributes. Then compare those lists using Except method. Each JSON object is serialized to string which is then split by ,. By splitting, JSON attributes are extracted. objArray is the array containing JSON objects.
List<List<string>> jsonAttList = new List<List<string>>();
int objArrayLength = objArray.Length;
for (int i = 0; i < objArrayLength; i++)
{
string objString = JsonConvert.SerializeObject(objArray[i]);
jsonAttList.Add(objString.Split(',').ToList());
}
Or shorter
List<List<string>> jsonAttList = new List<List<string>>();
objArray.ForEach(item => jsonAttList.Add(JsonConvert.SerializeObject(item).Split(',').ToList()));
Here are four examples you provided with one additional attribute.
[{"KB":"1","Id":"01","MemCode":1,"A":"2","B":"1","myObj":{"X":1,"Y":2},"C":"2010-01-01T00:00:00","D":1},
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","C":"2010-01-01T00:00:00","D":2}
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","myObj":{"X":1,"Y":3},"C":"2010-01-01T00:00:00","D":3},
{"KB":"1","Id":"01","MemCode":2,"A":"2","B":"1","myObj":{"X":1,"Y":2,"Z":3},"C":"2010-01-01T00:00:00","D":4}]
Difference between two JSON objects is list of strings.
Difference between first and second JSON object is list containing: "MemCode":1, "myObj":{"X":1, "Y":2} and "D":1}.
var difference01 = jsonAttList[0].Except(jsonAttList[1]).ToList();
Difference between first and third JSON object is list containing: "MemCode":1, "Y":2} and "D":1}.
var difference02 = jsonAttList[0].Except(jsonAttList[2]).ToList();
Difference between first and fourth JSON object is list containing: "MemCode":1, "Y":2} and "D":1}.
var difference03 = jsonAttList[0].Except(jsonAttList[3]).ToList();
Difference between fourth and first JSON object is list containing: "MemCode":2, "Y":2, "Z":3} and "D":4}.
var difference30 = jsonAttList[3].Except(jsonAttList[0]).ToList();

Related

In C# Convert List<dynamic> to List<string>

Suppose I have a List<dynamic> object containing strings:
var dlist = new List<dynamic>()
{
"test",
"test2",
"test3"
};
Is there any efficient way of converting this into a proper List<string> object? I know I can iterate over this list and cast each element to a string, then add this to the result list, but maybe some Linq magic could do the trick in one line?
I tried using some Select() combined with ToList() and Cast<string>, but to no avail. How should this be done properly?
Note: By saying "efficient" I mean of course number of lines of code. I do not take execution time or performance into account. Also - let's suppose I do not need to type check, there will always be strings only in this dynamic list.
EDIT: Okay, so in regards to comments on "why Cast wasn't working for you" - looks like I had another problem regarding the data I receive (I'm using Dapper) and that's why it didn't work. Sorry for the confusion, I thought my list converting was wrong while the problem was not related to this.
Given
var dList = new List<dynamic>() { /*...initialize list */ };
If you are interested in extracting all the strings in the collection, ignoring all other types, you can use:
// Solution 1: Include only strings, no null values, no exceptions thrown
var strings = dlist.OfType<string>().ToList();
If you are certain that all the items in the list are strings (it will throw an exception if they are not), you can use:
// Solution 2: Include strings with null values, Exception for other data types thrown
var strings = dlist.Cast<string>().ToList();
If you want the default string representation, with null for null values, of all the items in the list, you can use:
// Solution 3: Include all, regardless of data type, no exceptions thrown
var strings = dlist.Select(item => item?.ToString()).ToList();
This answer is for dart/flutter
Given
List<dynamic> dList;
You can use
var sList = List<String>.from(dlist);
to convert a List<dynamic> to List<String>

Adding JSON objects to a LIST Unity 3d and C#

I'm trying to add the contents of a JSON file to a LIST. Normally, I would use a loop to iterate through the objects, but using COUNT will not compile and when I use LENGTH, it counts the number of characters in the string.
Do I need to make it a JSONArray when the object is made, and if so, how do I do that? Or do I need another kind of loop? I'm using version 5.2.3f, the last XP compatible version.
Thanks!
You can use MiniJson:
var jsonString = File.ReadAllText(jsonFileName);
var list = Json.Deserialize(jsonString) as List<object>;

c# - cast array list in a string to an array list

I have a string variable like so, which I am receiving from a third party API:
string strArray = "[[1,\"56353657\",\"300\",\"test\",\"<img src=\\\"../Images/Edit.gif\\\" id=\\\"Edit\\\" />\",\"<img src=\\\"../Images/Delete.gif\\\" id=\\\"Delete\\\" />\"],[2,\"56353657\",\"400\",\"test\",\"<img src=\\\"../Images/Edit.gif\\\" id=\\\"Edit\\\" />\",\"<img src=\\\"../Images/Delete.gif\\\" id=\\\"Delete\\\" />\"]]";
I would like to be able to loop through this and retrieve the first 3 items in each of the arrays.
Could someone please advise me as to how to achieve this using c#?
Because values in your array of arrays are not of the same type you can try this way:
String[][] table = JsonConvert.DeserializeObject<String[][]>(strArray);
Then you can loop through this and, if you need, convert values to the desired type.

How do I deserialize a JSON array that contains only values?

I'm getting this result from a web function.
["767,20150221122715,121053103,14573465,1,7,302",
"767,20150221122756,121053165,14573375,1,0,302",
"767,20150221122840,121053498,14572841,1,12,124"]
Usually Json have PropertyName: Value
But this have an array of strings, and each string have the values separated by comma. I know what each value position mean.
I try using JsonConvert.DeserializeObject but couldn't make it work.
string deserializedProduct = JsonConvert.DeserializeObject<string>(json);
//and
List<string> deserializedProduct = JsonConvert.DeserializeObject<string>(json);
I can parse the string doing a split, but I'm wondering if there is an easy way.
To answer your question, according to to http://json.org/, it is a valid JSON value (an array of string).
To deserialize it according to this stack overflow question you should use
JsonConvert.DeserializeObject<List<string>>(json);
to convert it
The generic parameter to the DeserializeObject<T>() method is the type you want the deserializer to deserialize to. Your json string represents an array of strings so you should be deserializing to a collection of strings (typically List<string>).
var values = JsonConvert.DeserializeObject<List<string>>(json);
However, it isn't necessary to specify the type. There is a non-generic overload that returns object. It will (in this case) return an instance of a JArray with the appropriate values.
object values = JsonConvert.Deserialize(json);
Though, it would be better to return a more specific type if possible. To keep it more generalized, you can use JToken for the generic type or even more specifically, JArray.
var values = JsonConvert.Deserialize<JToken>(json); // good
var values = JsonConvert.Deserialize<JArray>(json); // better in this case

Deserialise JSON with Json.Net and test content of array

I'm deserialising JSON using JSON.Net along the same lines as the accepted solution to this question: Deserialize json object into dynamic object using Json.net. Essentially:
dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");
Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);
Difference being my array has strings rather than numbers. The above methods work fine. However, what I want to do is test if the array contains a particular value. If it was a typed array of strings I could use myArray.IndexOf("ValueToFind") and if it returns a value > -1 then it's in there. However, this isn't working and I think it's because it's actually an array of JValues rather than strings.
I can iterate through the array, cast each one to a string and then test (i.e. a foreach loop with an if statement inside) but I was hoping for a more succinct single line test. Can anyone advise if there is a simpler way to do the test?
Thanks
JSON.NET can seamlessly convert JArray to List<string>, so you can use
Console.WriteLine(d.array.ToObject<List<string>>().IndexOf("1"));
This works even with JSON integer array.
I got a slightly messier answer by first converting your dynamic array to a known type:
IEnumerable<JToken> d2 = d.array;
Then you can use Any as an extension method.
if (d2.Any(p => p.ToString() == "1")) //etc.

Categories

Resources