Issue
If dataGeneratorType is range then the value can be anything between dataGeneratorStart and dataGeneratorEnd. If dataGeneratorType is array with no length property then the value will be one value randomly selected from the array, otherwise it be two randomly selected values that equals to the length. If it is the object (which can be more nested) then it will again follow the above logic. But this is where it gets tricky for me. Is there any dynamic way to solve the problem in C#.
Input payload json
{
"temperature": {
"type": "int",
"dataGeneratorType": "range",
"dataGeneratorStart": -5,
"dataGeneratorEnd": 55
},
"salesAmount": {
"type": "float",
"dataGeneratorType": "array",
"dataGeneratorArray": [
0.51,
13.33,
20.01,
1.54
]
},
"city": {
"type": "string",
"dataGeneratorType": "array",
"dataGeneratorArray": [
"UK",
"Iceland",
"Portugal",
"Spain"
]
},
"relatedTags": {
"type": "array",
"dataGeneratorType": "array",
"dataGeneratorArray": [
"Sport",
"Hardware",
"Cycling",
"Magazines"
],
"length": 2
},
"salesDetail": {
"type": "object",
"dataGeneratorType": "object",
"dataGeneratorValue": {
"VAT": {
"type": "float",
"dataGeneratorType": "range",
"dataGeneratorStart": 0.0,
"dataGeneratorEnd": 20.0
},
"discountAmount": {
"type": "float",
"dataGeneratorType": "array",
"dataGeneratorArray": [
0.10,
0.15,
0.20
]
}
}
}
}
To output json:
{
"temperature": 20,
"salesAmount": 20.01,
"city": "Iceland",
"relatedTags": [
"Sport",
"Cycling"
],
"salesDetails": {
"VAT": 15.0,
"discount": 0.1
}
}
Solution
Please try this:
static string TransformJson(string inputPayload)
{
JObject obj = JObject.Parse(inputPayload);
var manipulatedObj = obj.DeepClone();
foreach (var child in obj)
{
var key = child.Key;
var t = child.Value["type"];
JToken genType;
if (!((JObject)child.Value).TryGetValue("dataGeneratorType", out genType))
{
continue; // genType is not found so, continue with next object.
}
var str = genType.Type == JTokenType.String ? genType.ToString().ToLower() : null;
switch (str)
{
case "range":
var r = new Random();
if (((string)t).ToLower() == "float")
{
var s = (float)child.Value["dataGeneratorStart"];
var e = (float)child.Value["dataGeneratorEnd"];
manipulatedObj[key] = r.NextDouble() * e;
}
else
{
var s = (int)child.Value["dataGeneratorStart"];
var e = (int)child.Value["dataGeneratorEnd"];
manipulatedObj[key] = r.Next(s, e);
}
break;
case "array":
var arr = child.Value["dataGeneratorArray"];
JToken lengthToken;
if (!((JObject)child.Value).TryGetValue("length", out lengthToken))
{
lengthToken = 2.ToString();
}
if ((string)t != "array")
{
manipulatedObj[key] = arr.OrderBy(a => a).LastOrDefault();
}
else
{
var count = arr.Count() >= (int)lengthToken ? (int)lengthToken : arr.Count();
var item = new JArray();
foreach (var m in Enumerable.Range(0, count).Select(i => arr[i]))
{
item.Add(m);
}
manipulatedObj[key] = item;
}
break;
case "object":
var transformJson = TransformJson(child.Value["dataGeneratorValue"].ToString());
manipulatedObj[key] = JObject.Parse(transformJson);
break;
default:
manipulatedObj[key] = child.Value["dataGeneratorValue"];
break;
}
}
return manipulatedObj.ToString(Formatting.Indented);
}
And use it as below:
var serializeObject = @"{""temperature"":{""type"":""int"",""dataGeneratorType"":""range"",""dataGeneratorStart"":-5,""dataGeneratorEnd"":55},""salesAmount"":{""type"":""float"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[0.51,13.33,20.01,1.54]},""relatedTags"":{""type"":""array"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[""Sport"",""Hardware"",""Cycling"",""Magazines""],""length"":2},""salesDetail"":{""type"":""object"",""dataGeneratorType"":""object"",""dataGeneratorValue"":{""VAT"":{""type"":""float"",""dataGeneratorType"":""range"",""dataGeneratorStart"":0.0,""dataGeneratorEnd"":20.0},""discountAmount"":{""type"":""float"",""dataGeneratorType"":""array"",""dataGeneratorArray"":[0.1,0.15,0.2]}}}}";
Console.WriteLine(serializeObject);
var outputJson = TransformJson(serializeObject);
Console.WriteLine(System.Environment.NewLine + "Modified Json = " + System.Environment.NewLine);
Console.WriteLine(outputJson);
I just added everything in one function but you can split into multiple functions and/or classes to make unit testing easier.
Here is the dotnet fiddle.
Answered By - sam Answer Checked By - Willingham (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.