I have a slash separated string format.
For Example
myDecision/data/buyerDecision/data/buy = food
myDecision/data/sellerDecision/data/sell = food
I want to convert it into following json format
"myDecision":{
"data":{
"buyerDesision":{
"data":{"buy":"food"}
},
"sellerDesision":{
"data":{"sell":"food"}
}
}
}
I tried a different solution, but it didn't work.
One way to solve this problem is by handcrafting JObject
s and then merging them. (This is not the most performant solution because it will recreate certain levels of the hierarchy several times.)
This approach differs from Benzara Tahar's proposed solution:
Json.Parse
JObject
hierarchy.The core logic can be implemented as this:
static JObject CreateHierarchy(Queue<string> pathLevels, JObject currentNode)
{
if (pathLevels.Count == 0) return currentNode;
var newNode = new JObject(new JProperty(pathLevels.Dequeue(), currentNode));
return CreateHierarchy(pathLevels, newNode);
}
pathLevels
: data, buyerDecision, data, myDescision
new JObject(
new JProperty("myDecision",
new JObject(
new JProperty("data",
new JObject(
new JProperty("buyerDecision",
new JObject(
new JProperty("data", currentNode)))))));
First, convert the input strings into a dictionary where
var dataSource = new List<string>
{
"myDecision/data/buyerDecision/data/buy = food",
"myDecision/data/sellerDecision/data/sell = food"
};
var mappings = dataSource.Select(data => data.Split('=', StringSplitOptions.RemoveEmptyEntries))
.ToDictionary(parts => parts[0].Trim(), parts => parts[1].Trim());
ArgumentException: 'An item with the same key has already been added
if multiple datasource entries want to set the same property.JObject
s from the entries
/
and then reverse the collectioncurrentNode
var objectsWithHierarchy = new List<JObject>();
foreach (var (path, innerMostValue) in mappings.Select(kv => (kv.Key, kv.Value)))
{
var entryLevels = path.Split('/').Reverse().ToArray();
objectsWithHierarchy.Add(CreateHierarchy(new Queue<string>(entryLevels.Skip(1)),
new JObject(new JProperty(entryLevels.First(), innerMostValue))));
}
Here we choose the first object from the objectsWithHierarchy
to collection to be the base JObject
on which we apply/merge the rest of the JObject
s.
var baseObject = objectsWithHierarchy.First();
var mergeSettings = new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Union};
foreach (var currentObj in objectsWithHierarchy.Skip(1))
{
baseObject.Merge(currentObj, mergeSettings);
}
Console.WriteLine(baseObject);
The output will be the following:
{
"myDecision": {
"data": {
"buyerDecision": {
"data": {
"buy": "food"
}
},
"sellerDecision": {
"data": {
"sell": "food"
}
}
}
}
}
Closing Thoughts